Почему это регулярное выражение, использующее «not» и backref, требует ленивого совпадения? - PullRequest
2 голосов
/ 26 августа 2010

При использовании оператора not ^ в сочетании с обратной ссылкой, зачем мне использовать ленивое совпадение?Кажется, что not должен нарушить совпадение.

Например:

<?php
preg_match('/(t)[^\1]*\1/', 'is this test ok', $matches);
echo $matches[0];
?>

Будет выводить this test вместоthis t, несмотря на то, что середина t не совпадает [^\1].Мне нужно использовать /(t)[^\1]*?\1/ для соответствия this t.

Кроме того

preg_match('/t[^t]*t/', 'is this test ok', $matches);

соответствует толькоthis t.

Что происходит и что я неправильно понимаю?

Ответы [ 2 ]

5 голосов
/ 26 августа 2010

Это не работает, потому что \1 здесь не является обратной ссылкой внутри класса символов.\1 интерпретируется как символ со значением ASCII 1.

Вместо этого вы можете использовать отрицательный обход, чтобы получить желаемый эффект:

'/(t)(?:(?!\1).)*\1/'
2 голосов
/ 26 августа 2010

Вы не можете использовать обратные ссылки внутри классов символов.[^\1] означает «любой символ, отличный от 1».

Вместо этого используйте /(t)(?:(?!\1).)*\1/.

(?:...) - это группа без захвата

(?!...) - это «негативный прогноз», утверждающий, что подвыражение не соответствует

(?!\1)., когда \1 является одним символом, означает «любой символ, который не соответствует \1

...