/ / Regex pasuje do wszystkiego od ostatniego wystąpienia któregokolwiek słowa kluczowego - regex, preg-match

Regex pasuje do wszystkiego od ostatniego wystąpienia któregokolwiek słowa kluczowego - regex, preg-match

Próbuję dopasować wszystko od ostatniego wystąpienia słowa kluczowego (foo lub bar) do końca łańcucha.

Przykład (a):

// 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);

Próbowałem następujące:

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

Myśląc, że pasuje do ostatniego wystąpienia foo i cały następujący tekst, ale zamiast tego pasuje do pierwszego wystąpienia.

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
)
*/

Uwaga Jestem zaniepokojony teorią i wnioskiem, jak to zrobić, więc proszę dodaj wyjaśnienie lub link do odpowiedniego wyjaśnienia.

Odpowiedzi:

3 dla odpowiedzi № 1
.+((foo|bar).+)$

. + dopasowuje wiele znaków z góry.

((foo | bar) dopasowuje i przechwytuje słowa kluczowe.

. +) dopasowuje i przechwytuje wiele postaci.

$ dopasowuje koniec ciągu / linii.

Na przykładzie:

This is foo and this is bar i like foo do you?
^---------^

2 dla odpowiedzi nr 2

Użyj chciwego pojedynku z przodu, aby zużyć jak najwięcej stogu siana, zanim zdołasz:

>>> 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?"

Grotniejszy sposób robienia tego to wykorzystanie negatywnego spojrzenia z wyprzedzeniem:

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