【发布时间】:2016-05-10 19:41:15
【问题描述】:
我正在用正则表达式标记一个字符串;这在g++-4.9 下正常工作,但在g++-5.3.1 下失败。
我有以下 txt 文件:
0001-SCAND ==> "Scandaroon" (from Philjumba)
0002-KINVIN ==> "King's Vineyard" (from Philjumba)
0003-HANNI ==> "Hannibal: Rome vs. Carthage" (from Philjumba)
0004-LOX ==> "Lords of Xidit" (from Philjumba)
我使用正则表达式、空格、引号对和括号对进行标记。例如,第一行应该标记如下:
0001-SCAND
==>
"Scandaroon"
(from Philjumba)
我写了以下std::regex:
std::regex FPAT("(\\S+)|(\"[^\"]*\")|(\\([^\\)]+\\))";
我正在使用以下方法标记字符串:
std::vector<std::string>
split( const std::string & input, const std::regex & regex ) {
std::sregex_token_iterator
first{input.begin(), input.end(), regex, 0},
last;
return {first, last};
}
这将返回匹配项。在g++-4.9 下,字符串按请求进行标记化,但在g++-5.3.1 下,它的标记化如下:
0001-SCAND
==>
"Scandaroon"
(from
Philjumba)
或者第三行被分词如下:
0003-HANNI
==>
"Hannibal:
Rome
vs.
Carthage"
(from
Philjumba)
可能是什么问题?
编辑:我调用函数如下:
std::string line("0001-SCAND ==> \"Scandaroon\" (from Philjumba)");
auto elems = split( line, FPAT );
编辑:根据@xaxxon 的反馈,我将返回迭代器替换为向量,但在g++-5.3 下仍然无法正常工作。
std::vector<std::string>
split( const std::string & input, const std::regex & regex ) {
std::sregex_token_iterator
first{input.begin(), input.end(), regex, 0},
last;
std::vector< std::string > elems;
elems.reserve( std::distance(first,last) );
for ( auto it = first; it != last; ++ it ) {
//std::cout << (*it) << std::endl;
elems.push_back( *it );
}
return elems;
}
【问题讨论】:
-
顺便说一句,原始字符串可能有助于避免额外的转义:
R"((\S+)|("[^"]*")|(\([^\)]+\)))"。 -
@Jarod42 谢谢,现在应该修复了。显然,在复制/粘贴期间添加了一个额外的
)。 -
请发布您是如何调用此函数的——如果您使用右值作为第一个参数调用它,则在您使用迭代器时该字符串可能无效。幕后的实际内存分配很容易在编译器版本之间发生变化,导致在旧版本中看起来还不错的内存在新版本中看起来不太好。
-
regex101.com/#pcre、
R"(("[^\"]*\")|(\([^\)])+\)|(\S+))"可以正常工作,但R"((\S+)|("[^\"]*\")|(\([^\)])+\))"不能...(\S+在末尾或开头)。 -
@xaxxon 已添加,感谢您的反馈。如果需要更多信息,请告诉我。