Использование несуществующей группы захвата в регулярном выражении¶
Идентификатор проверки Gixy: invalid_regex
При использовании регулярных выражений с группами захвата в директивах NGINX, таких как rewrite или в условиях if, вы можете ссылаться на захваченные группы с помощью $1, $2 и т.д. в строках замены или последующих директивах. Однако если вы ссылаетесь на группу захвата, которая не существует в шаблоне regex, NGINX обработает её как пустую строку, что может привести к неожиданному поведению.
Как это найти?¶
Следует проверить:
- Директивы rewrite, где строка замены ссылается на группы захвата (например, $1, $2), которые не существуют в шаблоне regex
- Директивы set внутри блоков if, которые ссылаются на группы захвата из шаблона regex условия if
- Не захватывающие группы, такие как (?:...), или встроенные модификаторы, такие как (?i), которые не создают нумерованные группы захвата
Примеры¶
Пример 1: Не захватывающий встроенный модификатор¶
Проблемная конфигурация:
server {
location / {
# (?i) — это флаг регистронезависимости, НЕ группа захвата
rewrite "(?i)/" $1 break;
}
}
Проблема: Шаблон (?i)/ использует (?i) для включения регистронезависимого сопоставления, но он не создаёт группу захвата. Ссылка $1 будет пустой.
Исправление:
server {
location / {
# Добавьте скобки для создания группы захвата
rewrite "(?i)/(.*)" /$1 break;
}
}
Пример 2: Отсутствующие группы захвата¶
Проблемная конфигурация:
server {
location / {
rewrite "^/path" $1 redirect;
}
}
Проблема: Шаблон ^/path не содержит групп захвата, поэтому $1 будет пустым.
Исправление:
server {
location / {
# Либо удалите ненужную ссылку $1
rewrite "^/path" /newpath redirect;
# Либо добавьте группу захвата, если необходимо
rewrite "^/path/(.*)$" /newpath/$1 redirect;
}
}
Пример 3: Ссылка на неправильный номер группы¶
Проблемная конфигурация:
server {
location / {
# Шаблон имеет только 1 группу захвата, но ссылается на $2
rewrite "^/(.*)$" /$1/$2 break;
}
}
Проблема: Шаблон содержит только одну группу захвата (.*), но замена ссылается и на $1, и на $2. Значение $2 будет пустым.
Исправление:
server {
location / {
# Добавьте вторую группу захвата, если необходимо
rewrite "^/([^/]+)/(.*)$" /$2/$1 break;
# Или удалите некорректную ссылку
rewrite "^/(.*)$" /prefix/$1 break;
}
}
Пример 4: Set в блоке if¶
Проблемная конфигурация:
server {
location / {
if ($uri ~ "^/path") {
set $x $1; # $1 не существует
}
}
}
Проблема: Шаблон regex в условии if не содержит групп захвата, поэтому $1 не определена.
Исправление:
server {
location / {
if ($uri ~ "^/path/(.*)$") {
set $x $1; # Теперь $1 содержит захваченное значение
}
}
}
Что можно сделать?¶
- Добавьте группы захвата в ваш шаблон regex, если вам нужно ссылаться на части совпавшей строки
- Удалите ненужные ссылки на группы захвата, если они вам не требуются
- Используйте правильные номера групп — помните, что нумерация групп начинается с 1, и
$0недоступен в NGINX - Помните, что не захватывающие группы не создают ссылок — шаблоны типа
(?:...),(?i),(?=...)не создают нумерованные группы - Тестируйте ваши шаблоны regex, чтобы убедиться, что они захватывают то, что вы ожидаете
Укрепляйте NGINX с поддерживаемыми RPM
Используйте NGINX Extras от GetPageSpeed для постоянно обновляемого NGINX и модулей на RHEL/CentOS/Alma/Rocky. Подробнее.