PHP регулярное выражение с дополнительным символом в конце

у меня есть следующая строка

https://www.example.com/int/de

и хотите сопоставить код языка в конце URL, например, ‘de’
я делаю это с этим регулярным выражением

/\..*\/.*\/([^\/?]*)\/?$/gi

Я также хотел бы получить тот же результат, если URL заканчивается косой чертой

Но с https://www.example.com/int/de/ я получаю только полное совпадение, но группа больше не соответствует ‘de’, хотя последний слеш необязательный в регулярном выражении

может кто то моя ошибка тут?

1

Решение

Ошибка не очевидна, но вполне обычна: «общий» шаблон сопоставления жадных точек сопровождается рядом необязательных подшаблонов (шаблонов, которые могут соответствовать пустой строке).

\..*\/.*\/([^\/?]*)\/?$ образец соответствует как это: \..* соответствует . и затем любые 0+ символов, как можно больше, затем начинается возврат \/ соответствовать / это самый правый / в строке (последней), затем .*\/ снова сопоставляет любые 0+ символов с максимально возможным количеством, а затем делает возврат двигателя еще дальше и вынуждает его отказаться от ранее найденного / и заново сопоставить / то есть до того, чтобы приспособиться к другому правому / в строке. Затем, наконец, приходит ([^\/?]*)\/?$, но предыдущий .*\/ уже сопоставлено в URL с / в конце, и индекс регулярного выражения находится в конце строки. Итак, с ([^\/?]*) может соответствовать 0+ символов кроме ? а также / а также \/? может соответствовать 0 / символы, они оба соответствуют пустым строкам в конце строки, и $ называет это днем, и механизм регулярных выражений возвращает действительное совпадение с пустым значением в группе 1.

Избавьтесь от жадных точек, используйте

'~([^\/?]+)\/?$~'

Увидеть regex demo

подробности

  • ([^\/?]+) — Группа захвата 1: один или несколько символов кроме ? а также /
  • \/? — 1 или 0 / символы
  • $ — в конце строки.
1

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

В качестве альтернативы вы могли бы рассмотреть возможность использования parse_url с взрываться а также RTRIM чтобы получить только последнюю часть.

$strings = [
"https://www.example.com/int/de/",
"https://www.example.com/int/de"];
foreach ($strings as $string) {
$parts = explode("/", rtrim(parse_url($string, PHP_URL_PATH), '/'));
echo end($parts) . "<br>";
}

Это даст вам:

de
de
2

Знак вопроса соответствует нулю или 1 символу. Вам нужно более одного, чтобы соответствовать «де». Попробуйте использовать .* или же .+ вместо ?,

Кстати, вероятно, более регулярный RegEx будет:
/.*\/([^/]*)\/?$/gi

Это регулярное выражение говорит «соответствует чему угодно (.*), после чего следует косая черта (\/), за которым следует то, что не является косой чертой, ноль или более раз ([^/]*), за которым следует дополнительная косая черта (\/?), за которым следует конец текста ($). Таким образом, все символы перед последней косой чертой и языковой частью будут сопоставлены в части регулярного выражения «сопоставить что угодно». Обратите внимание на круглые скобки вокруг части, которая представляет соответствие языка.

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