为什么我的Boost.Regex搜索只报告一次匹配迭代?

时间:2009-03-11 18:12:18

标签: c++ regex iterator greedy boost-regex

我试图找出字符串中有多少正则表达式匹配。我正在使用迭代器迭代匹配,并使用整数来记录有多少。

long int before = GetTickCount();
string text;

boost::regex re("^(\\d{5})\\s(\\d{8})\\s(.*)\\s(.*)\\s(.*)\\s(\\d{8})\\s(.{1})$");
char * buffer;
long length;
long count;
ifstream f;


f.open("c:\\temp\\test.txt", ios::in | ios::ate);
length = f.tellg();
f.seekg(0, ios::beg);

buffer = new char[length];

f.read(buffer, length);
f.close();

text = buffer;
boost::sregex_token_iterator itr(text.begin(), text.end(), re, 0);
boost::sregex_token_iterator end;

count = 0;
for(; itr != end; ++itr)
{
    count++;
}

long int after = GetTickCount();
cout << "Found " << count << " matches in " << (after-before) << " ms." << endl;

在我的例子中,count总是返回1,即使我把代码放在for循环中以显示匹配(并且有很多)。这是为什么?我做错了什么?

修改

TEST INPUT:

12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N

OUTPUT(不匹配):

  

在16 ms内找到1场比赛。

如果我将for循环更改为:

count = 0;
for(; itr != end; ++itr)
{
    string match(itr->first, itr->second);
    cout << match << endl;
    count++;
}

我得到这个作为输出:

12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
12345 12345678 SOME NAME SOMETHING 88888888 N
Found 1 matches in 47 ms.

4 个答案:

答案 0 :(得分:12)

嘿。你的问题是你的正则表达式。将(.\*)更改为(.\*?)(假设支持)。你认为你看到每一行都匹配,但实际上你看到整个文本被匹配,因为你的模式是贪婪的。

要查看说明的问题,请将循环中的调试输出更改为:

cout << "[" << match << "]" << endl;

答案 1 :(得分:0)

可以粘贴输入和输出。

如果count返回1,则表示字符串text中只有一个匹配。

答案 2 :(得分:0)

不太了解提升,但是(结束 - 它)是否有效?

答案 3 :(得分:0)

既然你说即使输出结果,计数仍然是一个,你可能会看一些东西来帮助诊断它:

  • 尝试输出每个循环迭代的计数,看看会发生什么。如果这只输出一次,那么循环只运行一次,你认为多次匹配真的是一场很长的比赛。
  • 如果可行,请尝试完全使用另一个变量名称:在声明多个count变量的情况下,您可能会获得一些范围阴影。

如果该循环正在执行多次,那么问题不在于您如何使用boost。无论你在做什么,boost都没有能力修改你没有传递给它的变量。 (当然,如果你要通过count来提升某个地方,那么这是另一种可能性。)

尽管存在所有可能性,但您拥有的第一个(.*)匹配所有内容直到输入结束(包括换行符)。尝试用([^ ]*)替换那些(除了空格之外的任何东西,所以匹配在找到空格时停止。