Почему мой поиск Boost.Regex сообщает только об одной итерации соответствия?

StackOverflow https://stackoverflow.com/questions/635705

Вопрос

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

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.
Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top