В настоящее время я работаю над маршрутизатором запросов для большого веб-сайта на основе 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>
,()
, Избегающие скобки игнорируются, конечно.<controller>
с ([\/]+)
, но тогда я должен был бы использовать массив, чтобы установить значение для него вместо этого. Что я пробовал:
Я читал исходный код каждого маршрутизатора, который я могу найти.
До сих пор я сделал пару неприятных маленьких регулярных выражений, но понял, что совершенно не понимаю, как их объединить и расширить.
Это соответствует скобкам, игнорируя экранированные: {([^{\\]*(?:\\.[^}\\]*)*)}
Это соответствует переменной со значением по умолчанию или без него: <([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))>
Это своего рода нечестивый ад, который заставил меня написать этот пост: <([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))(?: ?)(\([^{}<>\(\)\\]+\))?>
(Однако он соответствует переменным и разделам регулярных выражений.)
Кто-нибудь может дать мне какие-либо подсказки или даже пример исходного кода из библиотек, которые предлагают аналогичные функции? И если это действительно практически невозможно самому кодировать, то достаточно ли библиотеки для использования?
Если вы пытаетесь сопоставить домен, эта демонстрация regex101 должны соответствовать этим частям с именованными отдельными разделами.
С другой стороны, если вы пытаетесь сопоставить выражение маршрута, эта другая демонстрация regex101 может проанализировать указанные вами токены.
Возможно, я пропустил некоторые спецификации, но вы всегда можете оставить отзыв и объяснить, где он не работает (или даже обновить регулярное выражение на этом сайте и сохранить более новую версию).
Других решений пока нет …