2015-08-06 4 views
2

Я пытаюсь сопоставить последовательность символов в строке выделенных букв. Вот несколько примеров:PHP preg_match - regex неожиданно жадна

  • "ABCDE"
  • "ACCDE"
  • "быть"
  • "BCE"
  • "EFG"

Я хочу, чтобы соответствовать что-нибудь с «e», но я также хочу получить два результата для обратных ссылок. Если найдено «b», это должна быть первая обратная связь, а вторая - между «b» и «e». Если нет «b», это не имеет большого значения, какова вторая обратная связь. Вот мой тестовый код:

$regex = "(b)?(.*)?? e "; 

preg_match("/{$regex}/", " a b c d e ", $matches); 

Это возвращает $ совпадений «» (ничего) и «a b c d». Тем не менее, он работает, как я хочу, чтобы, если я удалить пространство на передней панели:

preg_match("/{$regex}/", "a b c d e ", $matches); 

Это возвращает $ матчи «б» и «в» г. Бинго! Но мне нужно это начальное пространство в строке стога сена. Я думал, что (б)? будет жадным из-за? в конце, и ожидал (. *) ?? быть ленивым. Но предпочитает ленивый (. *) ?? над ним.

Похоже, что первый приоритет регулярного выражения совпадает с началом строки, и только THEN считают жадность/лень. Это правда?

Адрес demo.

В реальном, не упрощенном регулярном выражении может быть несколько (b)? строки, и каждый из них на самом деле представляет собой сложное регулярное выражение, содержащее десятки символов, поэтому отрицание не будет возможным в (. *) ??.

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

Есть ли способ изменить регулярное выражение, чтобы выполнить то, что мне нужно?

+1

Попробуйте '(\ sb) (. *) E'. Проверьте [Демо] (https://regex101.com/r/zQ2gO1/1) – Tushar

+0

Это работает, если мы знаем, что есть «b», но он может быть не там. Я уточню вопрос более подробно. – Bonjiro

+0

@Bonjiro Какое ваше ожидаемое совпадение для 'a a c c e f'? –

ответ

0

Вы можете использовать следующее регулярное выражение:

(b)?((?:(?!b).)*)? e 

См demo

Дело в том, что вторая группа может не совпадать b, или он будет всегда «переопределение» первая опция группы.

+0

Спасибо, но если это первое место обязательно, оно не будет соответствовать «e», если в серии нет «b». Я немного изменил регулярное выражение выше и добавил демонстрационную ссылку с примерами для уточнения. – Bonjiro

+0

@Bonjiro: Я изменил свой ответ. Проверьте, работает ли он на вас. –

+0

Спасибо, что работает в упрощенной версии, которую я разместил здесь. Остается проблема в том, что в реальном регулярном выражении «b» представляет собой регулярное выражение длиной около 40 символов. Это не сработает (и станет настоящим беспорядком), чтобы скопировать это в [^ b]. Я надеялся, что будет способ настроить жадность, чтобы получить ответ. Вы знаете, почему регулярное выражение предпочитает совпадение с началом строки, независимо от жадности элементов внутри? – Bonjiro

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

  • Нет связанных вопросов^_^