2016-02-15 3 views
1

В Perl, я пытаюсь захватить слова как жетоны из следующих примеров строк (там всегда будет по крайней мере, одно слово):Regex: Захватив повторяющуюся группу групп (Perl)

"red"    ==> $1 = 'red'; 
"red|white"   ==> $1 = 'red'; $2 = 'white'; 
"red|white|blue" ==> $1 = 'red'; $2 = 'white'; $3 = 'blue'; 
etc. 

Узор Я вижу здесь: WORD, а затем п множеств "| WORD" [п> = 0]

Так от этого, у меня есть:

/(\ W +) ((?: \ |) (\ w +) *)/

Который, по моему мнению, всегда будет соответствовать первому СЛОВО, и если пара WORD существует, запишите это столько раз, сколько необходимо.

Это не работает, хотя, и я попробовал несколько вариантов, как:

/^ (\ W +) (\ | (\ W +)) * $/

... что мне не хватает?

+2

Вы не можете сделать это, как это. Когда вы повторяете группу захвата, предыдущее совпадение перезаписывается новым (при каждом повторении). Почему бы вам просто не использовать split? –

+0

Вы можете добиться этого с помощью Python PyPi regex, .NET Regex (CapureCollection), и есть возможность получить захват в библиотеке регулярных выражений Boost. –

+0

@ WiktorStribiżew: вы также можете добиться этого с помощью регулярных выражений Perl - просто не так, как пытается OP. – ruakh

ответ

2

Ваш первый регулярное выражение на самом деле не так — * находится в неправильном месте — но я остановлюсь на второй регулярное выражение, которое является правильным:

/^(\w+)(\|(\w+))*$/ 

Проблема заключается в том, что это регулярное выражение имеет три группы захвата : (\w+), (\|(\w+)), и (\w+). Таким образом, он будет заполнять, самое большее, три совпадающие переменные: $1, $2 и $3. Каждая переменная соответствия соответствует одной соответствующей группе захвата. Это не то, что вы хотите.

Что вы должны сделать вместо этого использовать split:

my @words = split /\|/, "red|white|blue"; 

# now $words[0] is 'red', $words[1] is 'white', $words[2] is 'blue' 
+0

Спасибо за ответ. Редактировать: Так что это невозможно сделать с помощью регулярных выражений? О:/^ (\ w +) (\ | \ w +) *? $/ –

+0

@JesseWalton: Число групп захвата в регулярном выражении является статическим/лексическим свойством регулярного выражения и не зависит от строка соответствует. Если вам нужно переменное количество групп захвата, то одно совпадение регулярных выражений не для вас. (''red | white | blue' = ~ m/^ (\ w +) (\ | (\ w +)) * $ /' похоже на запись '$ 1 = 'red'; $ 2 = '| white'; $ 3 = ' белый ', $ 2 =' | blue ', $ 3 =' blue''. Он продолжает использовать одни и те же переменные захвата.) – ruakh

Смежные вопросы