4

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

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 循环中以显示匹配项(并且有很多)。这是为什么?我究竟做错了什么?

编辑

测试输入:

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

输出(不匹配):

在 16 毫秒内找到 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

4 回答 4

12

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

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

cout << "[" << match << "]" << endl;
于 2009-03-11T18:25:45.903 回答
0

你能粘贴输入和输出。

如果 count 返回 1,则意味着您的 string 中只有一个匹配项text

于 2009-03-11T18:21:49.920 回答
0

对 boost 了解不多,但是 (end - itr) 有效吗?

于 2009-03-11T18:30:06.407 回答
0

既然您说即使输出结果,计数仍然是一个,您可能会查看几件事来帮助诊断它:

  • 尝试在每个循环迭代中输出计数,看看会发生什么。如果这只输出一次,那么循环只运行一次,而你认为​​的多个匹配实际上是一个很大的长匹配。
  • 如果可行,请尝试完全使用另一个变量名:您可能会在声明多个count变量的地方获得一些范围阴影。

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

很可能,您首先(.*)要匹配所有内容,直到输入几乎结束(包括换行符)。尝试将它们替换为([^ ]*)( 除了空格之外的任何内容,这样匹配就会在找到空格时停止。

于 2009-03-11T18:34:14.680 回答