Regex ungreedy с левой стороны (т. Е. Максимально узкое совпадение с обеих сторон) - PullRequest
5 голосов
/ 23 августа 2010

Допустим, я пытаюсь сопоставить /dog.*lab/ с этим текстом:

"У меня есть собака. Моя собака - черная лаборатория. Он был создан в лаборатории".

Жадно, это будет соответствовать " собака. Моя собака черная лаборатория. Он был создан в лаборатории ".

Я хочу найти совпадения, которыеузкий с обеих сторон.Если я использую модификатор ungreedy, например
/dog.*?lab/ или /dog.*lab/U, он будет соответствовать меньше, но все равно слишком много:
"собака. Моя собака - черная лаборатория"

Есть ли способ сделать мой поиск несвязным и слева, таким образом, сопоставляя только " собака - черная лаборатория "?

Большое спасибо.Извините за надуманный пример.

Ответы [ 3 ]

10 голосов
/ 23 августа 2010

Вы можете использовать прогнозное утверждение , которое исключает вхождение dog между dog и lab:

/dog(?:(?!dog).)*?lab/
2 голосов
/ 23 августа 2010

Это работает для меня:

$str = "I have a dog. My dog is a black lab. He was created in a laboratory.";
if(preg_match('/.*(dog.*?lab)/',$str,$m)) {
    var_dump($m);
}
1 голос
/ 23 августа 2010

Идея может состоять в том, чтобы попытаться использовать отрицательный набор символов, такой как [^.!?], который будет соответствовать всем символам, кроме ., ? и !, и поэтому вы можете быть уверены, что он находится в пределах то же предложение:

$string = "I have a dog. My dog is a black lab. He was created in a laboratory.";
preg_match('/dog[^.!?]*?lab/', $string, $match);
echo $match[0]; // Echoes "dog is a black lab"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...