[英]Splitting strings separated by \r\n into array of strings [C/C++]
我有包含例如"FirstWord\\r\\nSecondWord\\r\\nThird Word\\n\\r"
之類的字符串,依此類推...我想使用vector <string>
將其拆分為字符串數組,這樣我將得到:
FileName[0] == "FirstWord";
FileName[1] == "SecondWord";
FileName[2] == "Third Word";
另外,請注意第三個字符串中的空格。
到目前為止,這是我得到的:
string text = Files; // Files var contains the huge string of lines separated by \r\n
vector<string> FileName; // (optionaly) Here I want to store the result without \r\n
regex rx("[^\\s]+\r\n");
sregex_iterator FormatedFileList(text.begin(), text.end(), rx), rxend;
while(FormatedFileList != rxend)
{
FileName.push_back(FormatedFileList->str().c_str());
++FormatedFileList;
}
它可以工作,但是當涉及第三個字符串"Third Word\\r\\n"
,它只給我提供"Word\\r\\n"
。
誰能向我解釋正則表達式如何工作? 我有點困惑。
\\s
匹配所有空格,包括常規空格,制表符和其他一些空格。 您只想排除\\r
和\\n
,因此您的正則表達式應為
regex rx("[^\r\n]+\r\n");
編輯:這將不適合評論,也不會窮盡-正則表達式是一個相當復雜的主題,但我會盡力給出一個粗略的解釋。 如果您不熟悉正式的語言,那么所有這些都將變得更有意義,因此,我建議您仔細閱讀它,並且網上有無數的regex教程會更加詳細,您也應該閱讀。 好的。
您的代碼使用sregex_iterator
瀏覽正則表達式rx
匹配的字符串text
中的所有位置,然后將它們轉換為字符串並保存。 那么,什么是正則表達式?
正則表達式是將模式匹配應用於字符串的一種方式。 實際上,范圍可以從簡單的子字符串搜索到...好,再到復雜的子字符串搜索。 取而代之的只是尋找實例"oba"
中的字符串"foobar"
,例如,你可以搜索"oo"
后跟任意字符,然后"a"
,發現它在"foobar"
,以及在"foonarf"
。
為了啟用這種模式搜索,您必須有一種方法可以指定要查找的模式,而這樣的一種方法就是正則表達式。 細節因實現而異,但是通常它通過定義與特殊事物匹配的特殊字符或修改模式其他部分的行為來工作。 這聽起來令人困惑,所以讓我們考慮一些示例:
.
匹配任何單個字符 *
跟隨的某物*
匹配零或該事物的更多實例 +
事物將匹配該事物的一個或多個實例 [
, ]
包含一組字符; 然后整個事情與那些字符中的任何一個匹配。 ^
會將方括號表達式的選擇取反 仍然令人困惑。 因此,讓我們放在一起:
oo.a
是使用的正則表達式.
。 這將匹配“ oo.a”,“ ooba”,“ oona”,“ oo | a”以及其他任何東西,即兩個o后面跟一個字符,再跟一個a。 它不會與“ ooa”,“ oba”或“廢話”匹配。
a*
將匹配“”,“ a”,“ aa”,“ aaa”以及僅由a組成的其他任何序列。
[fgh]oobar
將匹配“ foobar”,“ goobar”和“ hoobar”中的任何一個。
[^fgh]oobar
將匹配“ aoobar”,“ boobar”,“ coobar”等,但不匹配“ foobar”,“ goobar”和“ hoobar”。
[^fgh]+oobar
將匹配“ aoobar”,“ aboobar”,“ abcoobar”,但不匹配“ oobar”,“ foobar”,“ agoobar”和“ abhoobar”。
就你而言
[^\r\n]+\r\n
將匹配既不是\\r
也不是\\n
后跟\\r\\n
的一個或多個字符的任何實例。 然后,您遍歷所有這些匹配項並保存text
的匹配部分。
我認為我可以合理地到這里深談。 這個兔子洞很深,這意味着您可以使用正則表達式來制作怪異的酷東西,但是您不應該指望在一兩天內掌握它們。 它的大部分遵循我剛才概述的內容,但是以真正的程序員的方式,大多數正則表達式實現超出了常規語言和表達式的數學范圍,並引入了有用但精打細算的內容。 勇者在前,但旅途是值得的。
一種簡單的替代方法是使用Boost中的split_regex。 例如。 split_regex(out,input,boost :: regex(“(\\ r \\ n)+”))其中out是字符串的向量,而input是輸入字符串。 下面是一個完整的示例:
#include <vector>
#include <iostream>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
using std::endl;
using std::cout;
using std::string;
using std::vector;
using boost::algorithm::split_regex;
int main()
{
vector<string> out;
string input = "aabcdabc\r\n\r\ndhhh\r\ndabcpqrshhsshabc";
split_regex(out, input, boost::regex("(\r\n)+"));
for (auto &x : out) {
std::cout << "Split: " << x << std::endl;
}
return 0;
}
regex rx("[^\\\\s]+\\r\\n");
,似乎是您要匹配字符串而不是拆分字符串。 否定的[^\\\\s]
字符類表示匹配任何字符,但不匹配空格( 水平空格或換行符 )。 在第三行中,有一個水平空間,因此您的正則表達式與水平空間旁邊的文本匹配。 在多行模式下, .
將匹配任何字符,但不匹配換行符。 您可以使用regex rx(".+\\r\\n");
而不是regex rx("[^\\\\s]+\\r\\n");
這也是一種方法:
char * pch = strtok((LPSTR)Files.c_str(), "\r\n");
while(pch != NULL)
{
FileName.push_back(pch);
pch = strtok(NULL, "\r\n");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.