[英]Parsing C++ strings
這里有很多關於發布字符串的文章,但實際上似乎不適合我的目的。
我正在使用std::string
和所有C ++標准庫,並且我有一個使用以下協議的文本文件:
TEXT1:TEXT2-TAB-TEXT3:TEXT4 TEXT5
當-TAB-
為\\t
。
我想將所有文本都轉換成字符串(也可以是數組)。 文件中的所有行都是以這種方式編寫的,我嘗試使用istringstream
但它沒有功能,例如: iss >> text1 >> ":" >> text2 >> "\\t" >> text3 >> ":" >> text4 >> " " >> text5
。
我實際上是否需要使用find
等的基本功能進行解析? 那將是大量的工作(因為我有幾個用不同格式編寫的文件,並且我需要為所有這些文件創建通用功能),但是如果我別無選擇,我會這樣做。
那么...有什么方法可以使用字符串之間的已知字符以下列方式解析字符串? 它不是特定的定界符,因為每一行都包含幾個定界符(一次是空格,然后是冒號,等等)。 我想使用C ++標准庫,而不要使用任何外部庫,如Boost。
編輯:C ++ 11。
由於您使用的是C ++ 11,並且文本行遵守協議,因此用於模式匹配和信息提取的工具就是regex庫中的功能。
符合您協議的模式可能看起來像這樣...
\\ w +:\\ w +-\\ t- \\ w +:\\ w + \\ s \\ w +
...使用默認的ECMAScript語法。 還有一些。
接下來,使用原始字符串文字來初始化正則表達式對象。
regex pat {R(“ \\ w +:\\ w +-\\ t- \\ w +:\\ w + \\ s \\ w +”)};
所以現在您的代碼可以看起來像這樣...
#include<regex>
...
regex pat{R("\w+:\w+-\t-\w+:\w+\s\w+")};
smatch m;
while (cin >> str) { // where str is your line of formatted text
bool match = regex_search(str, m, pat);
for (int i = 0; i < m.size(); i++) {
cout << m[i].str() << " "; // to make sure each component was matched
}
}
順便說一下, smatch就像一個容器一樣工作,並且可以迭代,因此非常方便。
注意 :上面的代碼不能保證能正常工作,它僅用作指導。
由於您有一個固定的單個字符來標記每個字段的結尾,因此諸如正則表達式之類的字詞會在過度殺傷時產生邊界。 我只是使用std::getline
來讀取每個字段。
我將從在一行中為字段定義一個結構開始,然后重載operator>>
以讀取這些結構之一:
struct line {
std::string text1, text2, text3, text4, text5;
friend std::istream &operator>>(std::istream &is, line &l) {
std::getline(is, l.text1, ':');
std::getline(is, l.text2, '\t');
std::getline(is, l.text3, ':');
std::getline(is, l.text4, ' ');
std::getline(is, l.text5);
return is;
}
};
這樣,您可以閱讀如下內容:
line x;
std::cin >> x;
...或者,如果您的整個文件中都包含這樣的行,則可以將它們全部讀入向量,例如:
std::ifstream infile("whatever.dat");
std::vector<line> lines {
std::istream_iterator<line>(lines),
std::istream_iterator<line>()
};
您可能應該使用std :: getline閱讀整行,然后解析該行,例如,使用std :: string的 find或find_first_of方法找到 '\\t'
字符。
如果可能,請至少切換到C ++ 11 ,因為C ++ 11的許多功能將使您編寫更少的代碼。 與匿名lambda一起使用時,特別是<algorithm>
std :: find會很有幫助。
當然,您應該更正式地定義可接受的輸入(也許使用一些EBNF表示法,至少在注釋中)。 特別是,您的TEXT1
和TEXT2
和TEXT3
以及TEXT4
和TEXT5
可以出現哪些確切字符。 用什么編碼? ( UTF-8具有多字節字符!)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.