C ++正则表达式排除双引号不起作用

时间:2017-02-14 14:10:18

标签: c++ regex

我正在考虑使用

这样的行输入文件
"20170103","MW JANE DOE","NL01 INGB 1234 5678 90","NL02 INGB 1234 5678 90","GT","Af","12,34","Internetbankieren","Mededeling_3"
"20170102","MW JANE DOE","NL01 INGB 1234 5678 90","NL02 INGB 1234 5678 90","GT","Af","12,34","Internetbankieren","Mededeling_2"
"20170101","MW JANE DOE","NL01 INGB 1234 5678 90","NL02 INGB 1234 5678 90","GT","Af","12,34","Internetbankieren","Mededeling_1"

。我想获得单独的字符串而不用双引号并将它们存储在std::vector<std::string>中。因此,举例来说,我希望20170101MW JANE DOENL01 INGB 1234 5678 90NL02 INGB 1234 5678 90GTAf12,34InternetbankierenMededeling_1作为结果。

我尝试使用代码

std::regex re("\"(.*?)\"");
std::regex_iterator<std::string::iterator> it (line.begin(),line.end(),re);
std::regex_iterator<std::string::iterator> end;
std::vector<std::string> lineParts;
std::string linePart="";

// Split 'line' into line parts and save these in the vector 'lineParts'.
while (it!=end)
{
    linePart=it->str();
    std::cout<<linePart<<std::endl; // Print substring.
    lineParts.push_back(linePart);
    ++it;
}

但是,双引号仍然包含在lineParts的元素中,即使我使用正则表达式"\"(.*?)\"",因此据说只保存双引号中的部分,而不是双引号自己。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

您有一个带有捕获组的模式。因此,当正则表达式找到匹配项时,双引号是整个匹配值的一部分(存储在[0]元素中),但捕获的部分存储在{ {1}}元素。

因此,您只需要访问捕获组#1内容:

[1]

请参阅regular-expressions.info 查找正则表达式匹配

  

当函数调用返回true时,您可以调用match_results对象的linePart=it->str(1); str()position()成员函数来获取匹配的文本或起始位置及其相对于主题字符串的匹配长度。不带参数调用这些成员函数或使用0作为参数来获得整体正则表达式匹配。 调用它们传递1或更大以获得特定捕获组的匹配。 length()成员函数指示捕获组的数量加上整个匹配的一个。因此,您可以将值高达size()传递给其他三个成员函数。

答案 1 :(得分:2)

正如其他人所说,regex_iterator::operator->返回match_resultsmatch_results::str默认为0:

  

sub_match中包含的第一个0(索引match_result)始终表示由regex和后续sub_matches生成的目标序列中的完全匹配表示子表达式匹配顺序对应于左括号,分隔regex

中的子表达式

因此,您的代码存在的问题是您没有使用linePart = it->str(1)

更好的解决方案是使用regex_token_iterator。有了whitch,您可以使用re直接初始化lineParts

vector<string> lineParts { sregex_token_iterator(cbegin(line), cend(line), re, 1), sregex_tokent_iterator() };

但我想指出介绍quoted正是您在这里尝试做的事情,以及更多(甚至为您处理转义报价! )不使用它只是一种耻辱。

您可能已经从流中获取了您的输入,但是在您不需要初始化istringstream的情况下,为了示例I&#l; ll的目的打电话给我:line。然后,您可以使用quoted填充lineParts,如下所示:

for(string linePart; line >> quoted(linePart); line.ignore(numeric_limits<streamsize>::max(), ',')) {
    lineParts.push_back(linePart);
}

Live Example