Есть ли способ сделать захват повторять произвольное количество раз в регулярном выражении? - PullRequest
3 голосов
/ 24 августа 2009

Я использую C ++ tr1 :: regex с грамматикой регулярных выражений ECMA. Я пытаюсь разобрать заголовок и вернуть значения, связанные с каждым элементом в заголовке.

Заголовок:

-Testing some text
-Numbers 1 2 5
-MoreStuff some more text
-Numbers 1 10

Что я хотел бы сделать, так это найти все строки "-Numbers" и поместить каждое число в свой собственный результат с помощью одного регулярного выражения. Как видите, строки «-Numbers» могут иметь произвольное количество значений в строке. В настоящее время я просто ищу "-Numbers ([\ s0-9] +)" и затем токенизирую этот результат. Мне было просто интересно, есть ли способ найти и маркировать результаты в одном регулярном выражении.

Ответы [ 3 ]

2 голосов
/ 24 августа 2009

Нет, нет.

0 голосов
/ 01 августа 2018

Проблема в том, что желаемое решение настаивает на использовании групп захвата. C ++ предоставляет инструмент regex_token_iterator для лучшей обработки (пример C ++ 11):

#include <iostream>
#include <string>
#include <regex>

using namespace std;

int main() {
    std::regex e (R"((?:^-Numbers)?\s*(\d+))");

    string input;

    while (getline(cin, input)) {
        std::regex_token_iterator<std::string::iterator> a{
            input.begin(), input.end(),
            e, 1,
            regex_constants::match_continuous
        };

        std::regex_token_iterator<std::string::iterator> end;
        while (a != end) {
            cout << *a << " - ";
            ++a;
        }
        cout << '\n';
    }

    return 0;
}

https://wandbox.org/permlink/TzVEqykXP1eYdo1c

0 голосов
/ 31 августа 2011

Я собирался задать тот же самый вопрос, и я вроде нашел решение.

Допустим, у вас есть произвольное количество слов, которые вы хотите запечатлеть.

"Есть четыре огня"

и

"Капитан Пикард - бомба"

Вы можете подумать, что решение:

/((\w+)\s?)+/

Но это будет соответствовать только всей входной строке и последней захваченной группе.

Что вы можете сделать, это использовать переключатель "g".

Итак, пример в Perl:

use strict;
use warnings;

my $str1 = "there are four lights";
my $str2 = "captain picard is the bomb";

foreach ( $str1, $str2 ) {
    my @a = ( $_ =~ /(\w+)\s?/g );
    print "captured groups are: " . join( "|", @a ) . "\n";
}

Вывод:

captured groups are: there|are|four|lights
captured groups are: captain|picard|is|the|bomb

Итак, есть решение, если ваш язык поддерживает эквивалент «g» (и я полагаю, что большинство из них…).

Надеюсь, это поможет тому, кто был в том же положении, что и я!

S

...