1

我正在使用 tr1::regex 尝试从字符串中提取一些匹配项。一个示例字符串可能是

asdf werq "one two three" asdf

我想摆脱这种情况:

asdf  
werq  
one two three  
asdf  

将引号中的东西组合在一起,所以我正在尝试使用 regex \"(.+?)\"|([^\\s]+)。我正在使用的代码是:

cmatch res;
regex reg("\"(.+?)\"|([^\\s]+)", regex_constants::icase);
regex_search("asdf werq \"one two three\" asdf", res, reg);

cout << res.size() << endl;
for (unsigned int i = 0; i < res.size(); ++k) {
    cout << res[i] << endl;
}

但输出

3
asdf

asdf

我究竟做错了什么?

4

2 回答 2

0

您可能想尝试以下正则表达式:

(?<=")[^"]*(?=")|[^"\s]\S*

引用时,当然需要转义:

"(?<=\")[^\"]*(?=\")|[^\"\\s]\\S*"

顺便说一句,您使用的代码可能只匹配目标字符串中的第一个单词,因为它不使用 match_any。您在结果中获得的 3 个项目可能是 (1) 整个匹配项,(2) 第一次捕获 - 为空,以及 (3) 第二次捕获,这是匹配的来源。

于 2010-08-29T04:39:48.270 回答
0

您的正则表达式引擎似乎不支持后向断言。为避免使用lookbehinds,您可以尝试以下方法:

"([^"]*)"|(\S+)

或引用:

"\"([^\"]*)\"|(\\S+)"

此正则表达式将起作用,但每个匹配项将有两个捕获,其中一个将为空(第一个 - 在未引用的单词的情况下,或第二个 - 在带引号的字符串的情况下)。

为了能够使用它,您需要遍历所有匹配项,并为每个匹配项使用非空捕获。

我对 TR1 的了解不够,所以我不确切知道如何迭代所有匹配项。但如果我没记错的话,res.size()总是等于 3。

例如,对于字符串asdf "one two three" werq,第一个匹配项将是:

res[0] = "asdf"              // the entire match
res[1] = ""                  // the first capture
res[2] = "asdf"              // the second capture

第二场比赛将是:

res[0] = "\"one two three\"" // the entire match including leading/trailing quotes
res[1] = "one two three"     // the first capture
res[2] = ""                  // the second capture

第三场比赛将是:

res[0] = "werq"              // the entire match
res[1] = ""                  // the first capture
res[2] = "werq"              // the second capture

HTH。

于 2010-08-29T16:07:18.413 回答