Регулярное выражение
Литерал регулярного выражения представляет собой регулярное выражение, используемое для операций сопоставления и разбора над строками.
Регулярные выражения предваряются символом r и заключаются в одиночные кавычки: r'…'. Используется синтаксис регулярных выражений Rust.
| Для изучения регулярных выражений в VRL рекомендуется использовать редактор и тестер выражений Rustexp. |
Обычные и специальные символы
| Представление | Описание | Эквиваленты |
|---|---|---|
|
Большинство символов представляют сами себя. |
|
|
Специальные символы |
|
|
Шестнадцатеричный код символа ASCII из двух цифр. |
|
|
Шестнадцатеричный код символа Unicode из четырех цифр. |
|
|
Шестнадцатеричный код символа Unicode из восьми цифр. |
|
|
Любой шестнадцатеричный код, которому соответствует символ Unicode. |
|
|
Символ горизонтальной табуляции. |
|
|
Символ перевода строки |
|
|
Символ возврата каретки. |
|
|
Символ вертикальной табуляции. |
|
|
Символ звукового сигнала. |
|
|
Символ смены страницы. |
|
Метасимволы и специальные символьные классы
| Представление | Описание и эквиваленты |
|---|---|
|
Метасимвол, обозначающий любой символ, кроме символа перевода строки |
|
Любой символ со свойством Unicode, указанным в фигурных скобках. Список поддерживаемых свойств представлен в документации репозитория regex. |
|
Любой символ, не имеющий свойства Unicode, указанного в фигурных скобках. |
|
Любой символ Unicode, относящийся к классу, обозначенному одной буквой:
Эквивалент: |
|
Любой символ Unicode, не относящийся к классу, обозначенному одной буквой. Эквивалент: |
|
Любой символ ASCII.
Эквивалент: |
|
Любой символ ASCII, доступный для печати: любой символ, кроме управляющих. Эквивалент: |
|
Любой отображаемый символ ASCII: любой символ, кроме управляющих и пробельных. Эквивалент: |
|
Любой символ Unicode, входящий в состав слов:
Эквивалент:
|
|
Любой символ Unicode, не входящий в состав слов. Эквивалент: |
|
Любая буква базового латинского алфавита, цифра ASCII или подчеркивание. Эквиваленты:
|
|
Любая буква базового латинского алфавита или цифра ASCII. Эквивалент: |
|
Любая буква базового латинского алфавита. Эквивалент: |
|
Любая прописная буква базового латинского алфавита. Эквивалент: |
|
Любая строчная буква базового латинского алфавита. Эквивалент: |
|
Любая десятичная цифра Unicode. Эквивалент: |
|
Любой символ, кроме десятичных цифр Unicode. Эквивалент: |
|
Любая десятичная цифра ASCII. Эквиваленты:
|
|
Любая шестнадцатеричная цифра. Эквивалент: |
|
Любой знак препинания ASCII. Эквивалент: |
|
Любой пробельный символ, то есть символ со свойством Unicode Эквивалент: |
|
Любой символ, кроме пробельных. Эквивалент: |
|
Любой пробельный символ ASCII. Эквивалент: |
|
Пробел или горизонтальная табуляция. Эквивалент: |
|
Любой управляющий символ ASCII. Эквивалент: |
Символьные классы и перечисление
| Представление | Описание | Найденные совпадения |
|---|---|---|
|
Последовательность |
|
|
Перечисление: одна из последовательностей |
|
|
Объединение: символы из указанных в квадратных скобках. |
|
|
Отрицание: все символы, кроме указанных в квадратных скобках. |
Все символы, кроме |
|
Диапазон: все символы между указанными. |
Символы от |
|
Вложенный класс: все символы, указанные хотя бы в одном из классов. |
Все символы, кроме |
|
Пересечение: символы, которые входят в оба класса. |
|
|
Разность: символы первого класса, которые не входят во второй класс. (Эквивалентно записи |
Все десятичные цифры ASCII, кроме |
|
Симметрическая разность: символы, которые входят лишь в один класс из указанных. |
|
Приоритет в перечислениях
В перечислениях проверяется каждый указанный вариант слева направо, поиск прекращается при первом совпадении.
Пример применения приоритета
| Используйте VRL-песочницу, чтобы проверить работу программы. |
.res = parse_regex_all!("authentication", r'authentication|auth', numeric_groups: true)
[
{
"0": "authentication"
}
]
Здесь функция с шаблоном r'authentication|auth' сначала пытается найти последовательность "authentication", и поскольку она полностью соответствует строке, именно это совпадение и будет возвращено. Однако, если изменить порядок вариантов, изменится и результат.
.res = parse_regex_all!("authentication", r'auth|authentication', numeric_groups: true)
[
{
"0": "auth"
}
]
При таком порядке вариантов сначала будет найдено "auth". На этом поиск остановится и вернет "auth", несмотря на то, что более длинный вариант "authentication" также соответствует строке.
Порядок вычисления символьных классов
-
Диапазоны: выражение
r'[а-яё]'равнозначно выражениюr'[[а-я]ё]'и выбирает все строчные буквы русского алфавита. -
Объединение: выражение
r'[ab&&bc]'равнозначно выражениюr'[[ab]&&[bc]]'и выбирает символы, которые входят в оба класса. -
Пересечение, разность, симметрическая разность: имеют одинаковый приоритет и вычисляются по порядку слева направо. Например, следующее выражение:
r'[\pL--\p\{Greek}&&\p\{Uppercase}]'равнозначно такому выражению:
r'[[\pL--\p\{Greek}]&&\p\{Uppercase}]'Эти выражения выбирают все буквенные символы в верхнем регистре, кроме греческих.
-
Отрицание: выражение
r'[^a-z&&[:xdigit:]]'равнозначно выражениюr'[^[a-z&&[:xdigit:]]]'.Эти выражения выбирают все символы, кроме тех, которые одновременно являются шестнадцатеричными цифрами и строчными латинскими буквами.
Группировка
Группы в круглых скобках определяют области действия флагов, квантификаторов, и перечислений.
Регулярные выражения поддерживают захват групп, что позволяет извлекать части шаблона как строки. Именованные группы захвата позволяют связать результаты извлечения с ключами.
| Представление | Описание |
|---|---|
|
Нумерованная группа захвата. |
|
Именованная группа захвата. Возможно обращение как по номеру, так и по ключу, указанному в угловых скобках. (Эквивалентно записи Имя может включать буквенные символы и цифры Unicode, а также символы |
|
Незахватываемая группа. |
|
Установка флага |
|
Выключение флага |
|
Установка флага |
Примеры группировки
Пример извлечения даты
Рассмотрим следующую функцию:
.res = parse_regex!("2012-12-12", r'(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})')
{
"res": {
"d": "12",
"m": "12",
"y": "2012"
}
}
Данная функция извлекает из строки с датой вида YYYY-MM-DD группы, содержащие год, месяц и число с ключами y, m и d соответственно.
Пример изменения формата даты
В следующем примере используется захват именованных групп, чтобы изменить формат даты.
replace_with("2022-01-05, 2023-08-25 и 2024-10-18", r'(?x)
(?P<y>\d{4}) # Год из 4 цифр Unicode.
-
(?P<m>\d{2}) # Месяц из 2 цифр Unicode.
-
(?P<d>\d{2}) # День из 2 цифр Unicode.
') -> |match| {
to_string(match.d) + "/" + to_string(match.m) + "/" + to_string(match.y)
}
"05/01/2022, 25/08/2023 и 18/10/2024"
Квантификаторы
Квантификатор после символа, символьного класса или группы определяет, сколько раз может встречаться предшествующее выражение.
При жадной квантификации возвращается наиболее длинная строка из возможных соответствий, при ленивой — наиболее короткая.
| Представление | Описание | Поведение |
|---|---|---|
|
Ноль или одно повторение |
Жадная квантификация |
|
Ноль или больше повторений |
Жадная квантификация |
|
Одно или больше повторений |
Жадная квантификация |
|
Ноль или одно повторение |
Ленивая квантификация |
|
Ноль или больше повторений |
Ленивая квантификация |
|
Одно или больше повторений |
Ленивая квантификация |
|
В точности |
Поведение не зависит от режима квантификации |
|
Как минимум |
Жадная квантификация |
|
Между |
Жадная квантификация |
|
Как минимум |
Ленивая квантификация |
|
Между |
Ленивая квантификация |
Примеры квантификаторов
Следующая функция ищет последовательности символов, заключенные в квадратные скобки.
.res = parse_regex_all!("[ERROR] [2024-10-05 10:01:00] [code: 500]", r'\[.*\]', numeric_groups: true)
[
{
"0": "[ERROR] [2024-10-05 10:01:00] [code: 500]"
}
]
Если заменить квантификатор на ленивый: r'\[.*?\]', функция вернет отдельные подстроки в квадратных скобках.
.res = parse_regex_all!("[ERROR] [2024-10-05 10:01:00] [code: 500]", r'\[.*?\]', numeric_groups: true)
[
{
"0": "[ERROR]"
},
{
"0": "[2024-10-05 10:01:00]"
},
{
"0": "[code: 500]"
}
]
Позиция в тексте
Следующие символы позволяют указать положение шаблона относительно начала и конца строки, а также границ слов.
| Представление | Описание |
|---|---|
|
Начало текста (в многострочном режиме — начало строки). |
|
Конец текста (в многострочном режиме — конец строки). |
|
Только в начале текста, в том числе в многострочном режиме. |
|
Только в конце текста, в том числе в многострочном режиме. |
|
Граница слова Unicode: символ, соответствующий классу |
|
Не на границе слова Unicode. |
|
Начало слова Unicode: символ класса |
|
Конец слова Unicode: символ класса |
|
Проверка начала слова Unicode только слева: символ класса |
|
Проверка конца слова Unicode только справа: символ класса |
Примеры использования позиций
Следующая функция возвращает последовательности алфавитно-цифровых и соединительных символов на границе слова.
.res = parse_regex_all!("@guest, @superuser, @root", r'(?P<user>\b\w+)')
[
{
"user": "guest"
},
{
"user": "superuser"
},
{
"user": "root"
}
]
Чтобы получить последовательности с символом @, изменим проверку начала слова.
.res = parse_regex_all!("@guest, @superuser, @root", r'(?P<user>\b{start-half}@\w+)')
[
{
"user": "@guest"
},
{
"user": "@superuser"
},
{
"user": "@root"
}
]
Флаги
Регулярные выражения позволяют использовать флаги — модификаторы, которые изменяют поведение поиска для всего выражения или группы. Флаги могут быть объединены: r'(?ixm)pattern', r'(?im)pattern'. Флаги можно включать и выключать внутри выражения.
| Опция | Описание | Состояние по умолчанию |
|---|---|---|
|
Режим без учета регистра: буквы в выражении соответствуют и прописным, и строчным буквам в строке. |
Выключен |
|
Многострочный режим:
|
Выключен |
|
Режим с поддержкой комментариев. Строчные комментарии должны начинаться с символа Пробелы при включенном режиме игнорируются. Чтобы добавить в шаблон пробел, используйте экранирование: |
Выключен |
|
Разрешает метасимволу точки |
Выключен |
|
Меняет местами значение квантификаторов |
Выключен |
|
Поддержка Unicode. |
Включен |
Пример флага
Рассмотрим следующую функцию:
.res = parse_regex!("AaAaAbbBBBb", r'(?i)a+(?-i)b+', numeric_groups: true)
{
"0": "AaAaAbb"
}
В начале регулярного выражения включается регистронезависимый режим, поэтому a+ соответствует буквам a и A. Однако b+, после выключения регистронезависимого режима, соответствует только строчной b.
Была ли полезна эта страница?