Выделения в регулярных выражениях
| Позиционные выделения Именованные выделения Сохранение позиционного выделения |
Регулярные выражения, используемые в директивах
location,
server_name,
if,
map
и ряде других, могут содержать выделения.
На выделенную подстроку можно сослаться либо по номеру, как
“$1”...“$9”, либо по имени.
Эти две формы отличаются тем, как долго выделенное значение
остаётся доступным.
Всё описанное ниже относится также к директивам server_name и map модуля stream.
Позиционные выделения
Позиционные выделения нумеруются в порядке следования выделяющих скобок в регулярном выражении:
location ~ ^/images/(.*)\.([a-z]+)$ {
# для запроса "/images/cats/tom.jpg"
# $1 равно "cats/tom", а $2 равно "jpg"
}
Позиционные выделения не являются переменными. Они образуют единый набор значений, общий для всех этих директив в процессе обработки запроса или соединения. Успешное сопоставление заменяет весь набор целиком, а неуспешное может его очистить. Поэтому значения доступны только до следующего сопоставления, которое может произойти в никак не связанной директиве.
Сопоставление может произойти и неявно. Поскольку переменные вычисляются только в момент использования, обращение к переменной map, в исходных значениях которой заданы регулярные выражения, приводит к сопоставлению с ними в этот момент, и успешное сопоставление заменяет позиционные выделения:
map $uri $mapped {
~^/(?<first>[^/]+)/ $first;
}
location ~ ^/images/(.*)$ {
set $name $1; # "cats/tom.jpg"
set $m $mapped; # "images"
set $name2 $1; # "images", а не "cats/tom.jpg"
}
Именованные выделения
Выделению можно дать имя:
location ~ ^/images/(?<name>.*)\.(?<ext>[a-z]+)$ {
...
}
Именованные выделения создают обычные переменные nginx,
в данном случае $name и $ext.
Их значения не заменяются при сопоставлении других регулярных выражений,
если только в них не используется то же имя выделения.
Поэтому именованные выделения предпочтительнее, если выделенное значение
нужно передать в директиву, отличную от той, в которой было выполнено
сопоставление.
Библиотека PCRE поддерживает именованные выделения, используя следующий синтаксис:
?<name>Совместимый с Perl синтаксис ?'name'Совместимый с Perl синтаксис ?P<name>Python-совместимый синтаксис
Сохранение позиционного выделения
Если позиционное выделение нужно использовать позднее и его нельзя заменить именованным, значение следует скопировать в переменную сразу после сопоставления с помощью директивы set (set в модуле stream):
location ~ ^/images/(.*)$ {
set $name $1;
}