Почему в отчете поиска Boost.Regex указана только одна итерация соответствия? - PullRequest
4 голосов
/ 11 марта 2009

Я пытаюсь выяснить, сколько совпадений регулярных выражений в строке. Я использую итератор для итерации совпадений, и целое число, чтобы записать, сколько их было.

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

ВЫХОД (без спичек):

Найдено 1 совпадений за 16 мс.

Если я изменю цикл 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 ]

12 голосов
/ 11 марта 2009

Хех. Ваша проблема - это ваше регулярное выражение. Измените (.\*) s на (.\*?) s (при условии, что это поддерживается). Вы думаете, что видите каждую строку совпадающей, но на самом деле вы видите, что весь текст совпадает, потому что ваш шаблон жадный.

Чтобы увидеть проиллюстрированную проблему, измените выходные данные отладки в вашем цикле на:

cout << "[" << match << "]" << endl;
0 голосов
/ 11 марта 2009

Поскольку вы говорите, что даже когда вы выводите результаты, счетчик все равно один, вы можете посмотреть на пару вещей, чтобы помочь в его диагностике:

  • Попробуйте вывести количество каждой итерации цикла и посмотрите, что получится. Если это выводится только один раз, то цикл запускается только один раз, и то, что вы считали множественными совпадениями, было действительно одним большим длинным совпадением.
  • Если это работает, попробуйте полностью использовать другое имя переменной: возможно, вы получаете некоторое затенение области, где вы объявили более одной count переменной.

Если этот цикл выполняется несколько раз, то проблема не в том, как вы используете boost. Независимо от того, что вы делаете, Boost не имеет возможности изменять переменную, которую вы не передаете ей. (Конечно, если вы передаете count для повышения, то это еще одна возможность.)

По всей вероятности, первое (.*), которое у вас есть, соответствует всему вплоть до конца ввода (включая переводы строки). Попробуйте заменить их на ([^ ]*) (что угодно, кроме пробела, поэтому сопоставление прекращается, когда он находит пробел.

0 голосов
/ 11 марта 2009

Не много знаете о бусте, но работает ли (конец - итр)?

0 голосов
/ 11 марта 2009

Можете ли вы вставить ввод, а также вывод.

Если count возвращает 1, это означает, что в вашей строке text есть только одно совпадение.

...