Я пытаюсь сопоставить последовательность символов в строке разнесенных букв. Вот несколько примеров:
Я хочу, чтобы все совпадало с «е», но я также хочу получить два результата для обратных ссылок. Если найдено «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);
Это возвращает $ совпадения «b» и «c d». Бинго! Но мне нужно это начальное пространство в строке сена. Я думал, что (б)? будет жадным из-за? в конце и ожидал (. *) ?? чтобы быть ленивым. Но он предпочитает ленивых (. *) ?? над ним.
Кажется, что первым приоритетом регулярного выражения является совпадение с начала строки, и только ТОГДА учитывают жадность / лень. Это правда?
Вот демонстрация.
В реальном, не упрощенном регулярном выражении может быть несколько (б)? строки, и каждая из них на самом деле является сложным регулярным выражением длиной в десятки символов, поэтому отрицание не будет возможным в (. *) ??.
Что я действительно пытаюсь сделать, так это то, что я хочу, чтобы и первая, и вторая группы были необязательными. Я хочу, чтобы первая группа была жадной, а вторая — жадной. В настоящее время вторая группа переопределяет первую, потому что она может соответствовать ранее в строке.
Есть ли способ изменить регулярное выражение, чтобы выполнить то, что мне нужно?
Вы можете использовать следующее регулярное выражение:
( b)?((?:(?!b).)*)? e
Увидеть демонстрация
Дело в том, что вторая группа не может соответствовать b
или он всегда будет «переопределять» первую необязательную группу.
Других решений пока нет …