Сопоставление сложного маршрута с регулярным выражением

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

Хотя я знаю, что есть готовые альтернативы и маршрутизаторы, которые могли бы сделать мою жизнь проще и имели бы те же функции (на самом деле, я искал их исходный код, чтобы попытаться решить эту проблему), я все еще занимаюсь программированием. Учиться и учиться создавать свои собственные может только хорошая вещь!


Примеры:

Вот пример одного из моих выражений маршрута:

  • <protocol (https?)>://<wildcard>.example.com/<controller>/{<lang=en (en|de|pl)>/}<name ([a-zA-Z0-9_-]{8})>

Это может соответствовать любому из этих одинаково хорошо:

  • http://www.example.com/test/en/hello_123
  • https://subdomain.example.com/another_test/hello_45

Возвращая мне хороший, удобный массив вроде этого (для последнего):

array(
'protocol' => 'http',
'wildcard' => 'subdomain',
'controller' => 'another_test',
'lang' => 'en',
'name' => "hello_45")

Во-первых, я также могу включить массив со значениями по умолчанию, которые будут переопределены значениями, найденными маршрутизатором. Так, например, я мог бы опустить <controller> переменная и просто написать test вместо этого, а затем использовать массив, добавив "controller"=>"test",


Вот правила:

  • Если нет совпадений, нет совпадений. Переменные должны существовать, а если нет, маршрут пропускается. Прощай. К счастью, необязательные разделы не должны существовать.
  • Что-нибудь между <> переменная Сбежал \<\> игнорируются, даже когда между ними. Соответствие области в URL-адресе должно быть сохранено в массиве результатов с именем переменной в качестве ключа.
  • Фигурные скобки {} пометить раздел как необязательный, и никогда не может быть внутри Переменная <>, Все, что находится между ними, может быть проигнорировано в цели — однако, если для любых переменных между ними указано значение по умолчанию, эта переменная должна быть добавлена ​​в массив результатов, используя имя в качестве ключа и значение по умолчанию в качестве значения , Удаленные скобки игнорируются.
  • Переменная не должна иметь значение по умолчанию, но если вы добавите ее, она должна быть после =, лайк <name=default>,
  • Правила регулярных выражений могут быть добавлены через пробел после имени или значения по умолчанию и заключены в скобки (), Избегающие скобки игнорируются, конечно.
  • Наконец, вы можете просто поместить правила Regex в квадратные скобки, где угодно, если вы не против сопоставить что-либо и не получить результат. Итак, я мог бы просто заменить <controller> с ([\/]+), но тогда я должен был бы использовать массив, чтобы установить значение для него вместо этого.

Что я пробовал:

Я читал исходный код каждого маршрутизатора, который я могу найти.

До сих пор я сделал пару неприятных маленьких регулярных выражений, но понял, что совершенно не понимаю, как их объединить и расширить.

  • Это соответствует скобкам, игнорируя экранированные: {([^{\\]*(?:\\.[^}\\]*)*)}

  • Это соответствует переменной со значением по умолчанию или без него: <([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))>

  • Это своего рода нечестивый ад, который заставил меня написать этот пост: <([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))(?: ?)(\([^{}<>\(\)\\]+\))?>
    (Однако он соответствует переменным и разделам регулярных выражений.)


Кто-нибудь может дать мне какие-либо подсказки или даже пример исходного кода из библиотек, которые предлагают аналогичные функции? И если это действительно практически невозможно самому кодировать, то достаточно ли библиотеки для использования?

2

Решение

Если вы пытаетесь сопоставить домен, эта демонстрация regex101 должны соответствовать этим частям с именованными отдельными разделами.

С другой стороны, если вы пытаетесь сопоставить выражение маршрута, эта другая демонстрация regex101 может проанализировать указанные вами токены.

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

1

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

Других решений пока нет …

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