Подтвердить что ты не робот

Исключение каталога из перенаправления регулярных выражений

Я хочу перенаправить все 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.

4b9b3361

Ответ 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].*_.* {
}

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