Regex соответствует всему, начиная с последнего появления любого ключевого слова - PullRequest
2 голосов
/ 26 марта 2011

Я пытаюсь сопоставить все от последнего вхождения ключевого слова (foo или bar) до конца строки.

Пример (а):

// I want to match ' foo do you?';
$source = 'This is foo and this is bar i like foo do you?';
$pattern = '/pattern/';
preg_match($pattern, $source, $matches);

Я попробовал следующее:

$pattern = '/( (foo|bar) .*)$/';

Думая, что это будет соответствовать последнему вхождению foo и всему следующему тексту, но вместо этого оно соответствует первому вхождению.

print_r($matches);

/*
Array
(
    [0] =>  foo and this is bar i like foo do you?
    [1] =>  foo and this is bar i like foo do you?
    [2] => foo
)
*/

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

Ответы [ 2 ]

4 голосов
/ 26 марта 2011
.+((foo|bar).+)$

. + Соответствует многим символам впереди.

((foo | bar) соответствует и фиксирует ваши ключевые слова.

. +) Соответствует и захватывает много символов.

$ соответствует концу строки / строки.

Используя ваш пример:

This is foo and this is bar i like foo do you?
                                   ^---------^
2 голосов
/ 26 марта 2011

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

>>> import re
>>> source = 'This is foo and this is bar i like foo do you?'
>>> pattern = '.*((?:foo|bar).*)'
>>> re.search(pattern, source).groups()[0]
'foo do you?'

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

>>> # Negative look-ahead for the pattern: (?!.*(?:foo|bar))
>>> pattern = '((?:foo|bar)(?!.*(?:foo|bar)).*)'
>>> re.search(pattern, source).groups()[0]
'foo do you?'
...