Исключение каталога из перенаправления регулярных выражений
Я хочу перенаправить все URL-адреса с символами подчеркивания на их пунктирный эквивалент.
например. /nederland/amsterdam/car_rental
становится /nederland/amsterdam/car-rental
. Для этого я использую описанную здесь технику: Как заменить подчеркивание тире на Nginx. Поэтому мой блок местоположения сопоставляется с:
location ~ (_)
Но я только хочу сделать это по URL не в пространстве имен /admin
. Для этого я попытался комбинировать регулярное выражение с отрицательным поиском: Регулярное выражение для соответствия строке, которая не содержит слова?. Теперь местоположение совпадает с:
(?=^(?!\/admin))(?=([^_]*))
Rubular сообщает строку /nederland/amsterdam/car_rental
, чтобы соответствовать регулярному выражению, а /admin/stats_dashboard
не соответствует, так же как и я. Однако, когда я применяю это правило к конфигурации nginx, сайт заканчивается в циклах перенаправления. Есть ли что-то, что я забыл?
UPDATE: я действительно не хочу переписывать что-либо в пространстве имен /admin
. Переменная подчеркивания к тире должна выполняться только во всех URL не в пространстве имен /admin
.
Ответы
Ответ 1
Порядок согласования местоположения Nginx таков, что местоположения, определенные с использованием регулярных выражений, проверяются в порядке их появления в файле конфигурации и поиск регулярных выражений заканчивается в первом совпадении.
С этими знаниями, на вашем месте, я просто определю одно местоположение, используя регулярное выражение для "admin" выше, чем для подчеркивания, которое вы получили из Ответ на переполнение стека, с которым вы связаны.
location ~ (\badmin\b) {
# Config to process urls containing "admin"
}
location ~ (_) {
# Config to process urls containing "_"
}
Любой запрос с admin
в нем будет обрабатываться первым блоком местоположения независимо от того, имеет ли он знак подчеркивания или нет, потому что перед этим подчеркивается соответствующий блок местоположения для подчеркивания.
** PS **
Как еще один ответ, отправленный cnst через пару дней после показа моих показаний, ссылка на документацию по размещенному мной положению, указанному мной, также указывает, что вы также можете использовать модификатор ^~
для соответствия папке /admin
и пропустить блок расположения для подчеркивания.
Я лично предпочитаю не использовать этот модификатор и предпочитаю группировать локали с регулярным выражением вместе с аннотированными комментариями, но это, безусловно, вариант.
Однако вам нужно быть осторожным, в зависимости от вашей установки, в качестве запросов, начинающихся с "/admin", но дольше, может совпадать с модификатором и приводить к неожиданным результатам.
Как я уже сказал, я предпочитаю, чтобы мой подход на основе regex был безопасным, зная, что никто не начнет произвольно изменять порядок вещей в файле конфигурации без ясного понимания.
Ответ 2
^(?!\/admin\b).*
Вам просто нужно это простое регулярное выражение с lookahead
.Смотрите демо.
https://regex101.com/r/uF4oY4/16
Ваше регулярное выражение завершится с ошибкой /nederland/amsterdam/car_rental
, так как оно имеет _
. Так будет рассмотрена только строка /nederland/amsterdam/car
.
или
вы можете использовать
rewrite ^(?!\/admin\b)([^_]*)_(.*)$ $1-$2;
Ответ 3
Вы явно не указали один или другой способ, но похоже, что у вас, вероятно, есть только одно пространство имен /admin
, которое формирует префикс $uri
и будет соответствовать регулярному выражению ^/admin.*$
; позвольте мне представить два неконфликтных варианта конфигурации на основе такого предположения.
Как и другие, вы можете использовать отдельный location
для /admin
.
Однако, в отличие от другого ответа, я бы посоветовал вам определить его с помощью префиксной строки и использовать модификатор ^~
, чтобы не проверять регулярные выражения после успешного совпадения.
location ^~ /admin {
}
В качестве альтернативы или даже дополнительно для дополнительного спокойствия и безупречного подхода вместо использования того, что, как представляется, является не-POSIX-регулярным выражением из связанного ответа (если мое чтение re_format (7) на OpenBSD), подумайте о том, что намного проще, гарантированно понятному большинству людей, которые утверждают, что они знают, что такое RE, и работают повсюду, не говоря уже о том, что, вероятно, будет более эффективным, учитывая, что вы уже знаете, что это путь ^/admin.*
, который вы хотите исключить:
location ~ ^/[^a][^d][^m][^i][^n].*_.* {
}
Для достижения вашей цели вы можете использовать либо одно из этих двух решений, либо даже оба более жесткие и надежные.