Необязательное регулярное выражение группы без захвата

Я борюсь с простой схемой, где мне нужно сопоставить максимум 3 строки или минимум 2

Может быть :

banana-split.taste

Или же

banana.taste

То, что я хочу, это все после и до момента.
Но если в строке до точки существует дефис, я хочу строку между дефисом и точкой

С моими примерами это будет выглядеть так:

Пример 1

match[1] = banana
match[2] = split
match[3] = taste

Пример 2

match[1] = banana
match[2] =
match[3] = taste

Я попробовал использовать позитивный взгляд вперед / назад, но чувствую, что использую его плохо

(.+)(?<=\-)(.*?)?\.(.+)

С этим я могу получить первый пример, но не второй

2

Решение

Используйте отрицательные классы символов и необязательную группу:

([^-]+)(?:-([^.]+))?\.(.+)

Увидеть regex demo

подробности:

  • ([^-]+) — Группа 1: один или несколько символов, кроме - как можно больше
  • (?:-([^.]+))? — необязательная группа, соответствующая 1 или 0 вхождениям:
    • - — дефис
    • ([^.]+) — Группа 2: один или несколько символов, кроме . как можно больше
  • \. — точка
  • (.+) — любые 1+ символов, кроме символов разрыва строки
2

Другие решения

В ответе Виктора нет ничего плохого; Я высоко ценю качество его ответов.

Чисто для образовательных целей, я хотел бы объяснить, что preg_match() не единственная основанная на регулярных выражениях функция для извлечения подстрок из строки. Рассмотрим эту однострочную:

Метод:

var_export(preg_split('/[-\.]/',$str));

Входы / выходы:

$str='banana-split.taste';  // ['banana','split','taste']
$str='banana.taste';  // ['banana','taste']

Обратите внимание, как preg_split() не использует группы захвата (поэтому нет пустых групп захвата) и не включает (часто бесполезное) совпадение полной строки в свой вывод.

Я не знаю, какой процесс вы используете, но если это упростит ваш процесс, то я рад, что принял участие.

2

По вопросам рекламы [email protected]