Выражения
Синтаксис
В данной статье при описании выражений приняты следующие обозначения:
|
Комментарий
Комментарий используется для целей документирования программного кода и обозначается символом #
. Каждая строка комментария должна начинаться с символа #
. В настоящее время VRL не поддерживает многострочные комментарии.
Примеры
# комментарий
# комментарий # из нескольких строк
Ключевые слова
Ключевые слова — это зарезервированные слова, используемые для базовых функций языка, таких как работа с условиями (if
). Они не могут использоваться для наименования переменных или других пользовательских директив. Следующие слова зарезервированы:
-
abort
-
as
-
break
-
continue
-
else
-
false
-
for
-
if
-
impl
-
in
-
let
-
loop
-
null
-
return
-
self
-
std
-
then
-
this
-
true
-
type
-
until
-
use
-
while
Литералы
Пустое значение (Null)
Литерал пустого значения представляет отсутствие определенного значения.
Пример
null
Логическое значение (Boolean)
Литерал типа логическое выражение представляет собой двоичное значение, которое может быть только истинным (true
) или ложным (false
).
Примеры
true
false
Целое число (Integer)
Литерал типа целое число — это десятичное представление 64-битного целого числа со знаком.
Характеристики
Ограничения
Целые числа в VRL могут находиться в диапазоне от -263 + 1
до 263 - 1
. Числа за пределами этого диапазона "оборачиваются", то есть переносятся на другой конец диапазона.
Подчеркивание
В целых числах может использоваться символ _
для улучшения читаемости, например, для разделения разрядов. Например, 1_000_000
.
Примеры
1_000_000
1000000
Число с плавающей точкой (Float)
Литерал типа число с плавающей точкой представляет собой десятичное представление 64-битного числа с плавающей точкой (в частности, тип "binary64", определенный в IEEE 754-2008), включая знак.
Десятичный литерал с плавающей точкой состоит из целой части (десятичные цифры), десятичной точки и дробной части (десятичные цифры).
Характеристики
Ограничения
Числа с плавающей точкой в VRL могут находиться в диапазоне от -1.7976931348623157E+308f64
до 1.7976931348623157E+308f64
. Числа за пределами этого диапазона "оборачиваются", то есть переносятся на другой конец диапазона.
Подчеркивания
В числах с плавающей точкой может использоваться символ _
для улучшения читаемости, например, для разделения разрядов. Например, 1_000_000.0
.
Примеры
1_000_000.01
1000000.01
1.001
Метка времени (Timestamp)
Литерал метки времени — это нативная метка времени, выраженная в формате RFC 3339 с точностью до наносекунды.
Метки времени определяются с помощью символа t
и заключаются в одинарные кавычки (t'2021-02-11T10:32:50.553955473Z'
).
Примеры
t'2021-02-11T10:32:50.553955473Z'
t'2021-02-11T10:32:50.553Z'
t'2021-02-11T10:32:50.553-04:00'
Характеристики
Часовые пояса
Как определено в формате RFC 3339, литералы меток времени поддерживают UTC и локальные смещения времени.
Строка (String)
Литерал строки представляет собой строку, закодированную в UTF-8. Строковые литералы могут быть сырыми или интерпретированными.
Сырые (raw) строковые литералы состоят из неинтерпретированных (неявно закодированных в UTF-8) символов между одинарными кавычками и обозначаются символом s
(s'…'
). В частности, обратная косая черта не имеет особого значения, и строка может содержать символы новой строки.
Интерпретированные строковые литералы представляют собой последовательности символов между двойными кавычками ("…"
). Внутри кавычек может находиться любой символ, кроме неэкранированного символа новой строки и неэкранированной двойной кавычки. Текст между кавычками представляет собой результат литерала, с экранированными символами, интерпретируемыми как показано ниже. Строки можно шаблонизировать, заключив переменные в {{..}}
. Значения переменных вставляются в строку на указанной позиции.
Примеры
"Hello, world! 🌎"
"Hello, world! \u1F30E"
"Hello, \ world!"
"Hello, {{ planet }}!"
s'Hello, world!'
s'{ "foo": "bar" }'
Характеристики
Экранирование
Специальные символы, такие как символы новой строки, могут быть выражены с помощью экранирования обратной косой чертой.
Представление | Описание |
---|---|
|
Символ Unicode из 24 бит (до 6 цифр) |
|
Перевод строки |
|
Возврат каретки |
|
Табуляция |
|
Обратная косая черта |
\0 |
Пустой символ |
|
Двойные кавычки |
|
Одинарные кавычки |
\{ |
Фигурная скобка |
Шаблоны
Строку можно шаблонизировать, заключив имя переменной в {{..}}
. Значение переменной вставляется в строку на этой позиции во время выполнения. Переменная должна быть строкой. Поддерживаются только переменные. Если вы хотите вставить путь из события, вы должны сначала присвоить его переменной. Чтобы вставить {{
в строку, его можно экранировать с помощью символа \
: \{{..\}}
.
Многострочные литералы
Длинные строки можно разбить на несколько строк, добавив обратную косую черту перед символом новой строки. Символ новой строки и любые пробелы в начале следующей строки не будут включены в строку.
Конкатенация
Строки можно объединять с помощью оператора +
.
Недопустимые символы
Недопустимые последовательности UTF-8 заменяются символом �
.
Регулярное выражение (Regex)
Литерал регулярного выражения представляет собой регулярное выражение, используемое для сопоставления и разбора строк.
Регулярные выражения определяются с помощью символа r
и заключаются в одинарные кавычки: r'…'
. Используется синтаксис регулярных выражений Rust.
Для изучения регулярных выражений в VRL рекомендуется использовать редактор и тестер выражений Rustexp. |
Обычные и специальные символы
Представление | Описание | Эквиваленты |
---|---|---|
|
Большинство символов представляют сами себя. |
|
|
Специальные символы |
|
|
Шестнадцатеричный код символа ASCII из двух цифр. |
|
|
Шестнадцатеричный код символа Unicode из четырех цифр. |
|
|
Шестнадцатеричный код символа Unicode из восьми цифр. |
|
|
Любой шестнадцатеричный код, которому соответствует символ Unicode. |
|
|
Символ горизонтальной табуляции. |
|
|
Символ перевода строки |
|
|
Символ возврата каретки. |
|
|
Символ вертикальной табуляции. |
|
|
Символ звукового сигнала. |
|
|
Символ смены страницы. |
|
Метасимволы и специальные символьные классы
Представление | Описание | Эквиваленты |
---|---|---|
|
Метасимвол, обозначающий любой символ, кроме символа перевода строки |
|
|
Любой символ со свойством Unicode, указанным в фигурных скобках. Список поддерживаемых свойств описан в документе. |
|
|
Любой символ, не имеющий свойства Unicode, указанного в фигурных скобках. |
|
|
Любой символ Unicode, относящийся к классу, обозначенному одной буквой:
|
|
|
Любой символ Unicode, не относящийся к классу, обозначенному одной буквой. |
|
|
Любой символ ASCII. |
|
|
Любой символ ASCII, доступный для печати: любой символ, кроме управляющих. |
|
|
Любой отображаемый символ ASCII: любой символ, кроме управляющих и пробельных. |
|
|
Любой символ Unicode, входящий в состав слов: буква или идеограмма любой письменности, диакритический символ, цифра, знак пунктуации, соединяющий слова (например, |
|
|
Любой символ Unicode, не входящий в состав слов. |
|
|
Любая буква базового латинского алфавита, цифра ASCII или подчеркивание. |
|
|
Любая буква базового латинского алфавита или цифра ASCII. |
|
|
Любая буква базового латинского алфавита. |
|
|
Любая прописная буква базового латинского алфавита. |
|
|
Любая строчная буква базового латинского алфавита. |
|
|
Любая десятичная цифра Unicode. |
|
|
Любой символ, кроме десятичных цифр Unicode. |
|
|
Любая десятичная цифра ASCII. |
|
|
Любая шестнадцатеричная цифра. |
|
|
Любой знак препинания ASCII. |
|
|
Любой пробельный символ (символ со свойством Unicode |
|
|
Любой символ, кроме пробельных. |
|
|
Любой пробельный символ ASCII. |
|
|
Пробел или горизонтальная табуляция. |
|
|
Любой управляющий символ ASCII. |
|
Символьные классы и перечисление
Представление | Описание | Найденные совпадения |
---|---|---|
|
Последовательность |
|
|
Перечисление: одна из последовательностей |
|
|
Объединение: символы из указанных в квадратных скобках. |
|
|
Отрицание: все символы, кроме указанных в квадратных скобках. |
Все символы, кроме |
|
Диапазон: все символы между указанными. |
Символы от |
|
Вложенный класс: все символы, указанные хотя бы в одном из классов. |
Все символы, кроме |
|
Пересечение: символы, которые входят в оба класса. |
|
|
Разность: символы первого класса, которые не входят во второй класс. (Эквивалентно записи |
Все десятичные цифры ASCII, кроме |
|
Симметрическая разность: символы, которые входят лишь в один класс из указанных. |
|
Приоритет в перечислениях:
В перечислениях проверяется каждый указанный вариант слева направо, поиск прекращается при первом совпадении.
Пример
.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
соответственно.
Квантификаторы
Квантификатор после символа, символьного класса или группы определяет, сколько раз может встречаться предшествующее выражение.
При жадной квантификации возвращается наиболее длинная строка из возможных соответствий, при ленивой — наиболее короткая.
Представление | Описание | Поведение |
---|---|---|
|
Ноль или одно повторение |
Жадная квантификация |
|
Ноль или больше повторений |
Жадная квантификация |
|
Одно или больше повторений |
Жадная квантификация |
|
Ноль или одно повторение |
Ленивая квантификация |
|
Ноль или больше повторений |
Ленивая квантификация |
|
Одно или больше повторений |
Ленивая квантификация |
|
В точности |
|
|
Как минимум |
Жадная квантификация |
|
Между |
Жадная квантификация |
|
Как минимум |
Ленивая квантификация |
|
Между |
Ленивая квантификация |
Примеры
Следующая функция ищет последовательности символов, заключенные в квадратные скобки.
.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
.
В следующем примере используется захват именованных групп, чтобы изменить формат даты.
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"
Массив
Литерал массива представляет собой набор выражений, разделенных запятыми, который создает непрерывный массив. Массив может быть динамически расширен.
Примеры
[]
["первый", "второй", "третий"]
["смешанный", 1, 1.0, true, false, {"foo": "bar"}]
[ "первый-уровень", [ "второй-уровень", [ "третий-уровень" ] ] ]
[.поле1, .поле2, to_int!("2"), variable_1]
[ "выражения", 1 + 2, 2 == 5, true || false ]
Объект
Литерал объекта представляет собой расширяемую структуру ключ/значение, которая синтаксически эквивалентна JSON-объекту.
Верно сформированный JSON-документ является допустимым объектом VRL.
Характеристики
Упорядочивание
Поля объекта упорядочены по ключу в алфавитном порядке по возрастанию. Таким образом, операции, такие как кодирование в JSON, производят строку с ключами, упорядоченными в алфавитном порядке.
Примеры
{ "поле1": "значение1", "поле2": [ "значение2", "значение3", "значение4" ], "поле3": { "поле4": "значение5" } }
{ "поле1": ."некий_путь", "поле2": some_variable, "поле3": { "вложенное_поле": "некое значение" } }
Динамические выражения
Переменная
Выражение переменной именует переменные. Переменная представляет собой последовательность из одной или нескольких букв, цифр и подчеркиваний. Первый символ в переменной должен быть буквой или цифрой.
Синтаксис
first ~ (trailing)*
Элемент | О писание |
---|---|
first |
Первый символ может быть только буквенно-цифровым символом ( |
trailing |
Последующие символы должны содержать только ASCII буквенно-цифровые символы и подчеркивания ( |
Примеры
Простая переменная
my_variable = 1
1
Переменная с путем
my_object = { "one": 1 } my_object.one
1
Элемент | Описание |
---|---|
target |
Цель должна быть путем с возможной второй переменной для обработки ошибок, если правая часть может возвращать ошибки. |
error |
Позволяет необязательное присваивание ошибок, когда выражение справа может возвращать ошибки. Это обычно используется при вызове функций, которые могут возвращать ошибки. |
operator |
Оператор разделяет |
expression |
Если Если |
Примеры
Присваивание пути
.message = "Hello, World!"
Присваивание по вложенному пути
.parent.child = "Hello, World!"
Двойное присваивание
.first = .second = "Hello, World!"
Присваивание элемента массива
.array[1] = "Hello, World!"
Присваивание переменной
my_variable = "Hello, World!"
Hello, World!
Присваивание со слиянием объектов
my_variable = {"message": "Hello, World!"} my_variable |= {"level": "info"}
{ "level": "info", "message": "Hello, World!" }
Присваивание с возможностью ошибки (успех)
.parsed, .err = parse_json("{\"Hello\": \"World!\"}")
Присваивание с возможностью ошибки (ошибка)
.parsed, .err = parse_json("malformed")
Путь
Выражение пути представляет собой последовательность сегментов, разделенных точками, которые определяют местоположение значения внутри объекта. Ведущая "." означает, что путь указывает на событие. Ведущий "%" означает, что путь указывает на метаданные события.
Синтаксис
root_path ~ path_segments
Элемент | Описание |
---|---|
root_path |
Все пути должны начинаться с
|
path_segments |
Сегменты пути обозначают сегмент вложенного пути. Каждый сегмент должен быть отделен точкой в начале и может содержать только буквенно-цифровые символы и подчеркивание ( |
Примеры
Корневой путь события
{ "message": "Hello, World!" }
.
{ "message": "Hello, World!" }
Корневой путь метаданных
{ "message": "Hello, World!" }
%
{}
Путь верхнего уровня
{ "message": "Hello, World!" }
.message
Hello, World!
Вложенный путь
{ "parent": { "child": "Hello, World!" } }
.parent.child
Hello, World!
Объединение вложенных путей
{ "grand_parent": { "parent2": { "child": "Hello, World!" } } }
.grand_parent.parent1.child || .grand_parent.parent2.child
Hello, World!
Путь в кавычках
{ "parent.key.with.special characters": { "child": "Hello, World!" } }
."parent.key.with.special characters".child
Hello, World!
Путь к первому элементу массива
{ "массив": [ "первый", "второй" ] }
."массив"[0]
"первый"
Путь ко второму элементу массива
{ "массив": [ "первый", "второй" ] }
."массив"[1]
"второй"
Индекс
Выражение индекса обозначает элемент массива. Индексы массивов в VRL начинаются с нуля.
Синтаксис
"[" ~ index ~ "]"
Элемент | Описание |
---|---|
index |
Индекс представляет собой нулевую позицию элемента. |
Примеры
Выражение индекса массива
{ "массив": [ "первый", "второй" ] }
."массив"[0]
"первый"
Присваивание
Выражение присваивания присваивает результат выражения справа от знака равенства цели слева (пути или переменной).
Синтаксис
target ~ ("," ~ error)? ~ operator ~ expression
Аргумент | Значение |
---|---|
target |
Цель должна быть переменной, индексом или путем. Возможно присваивание сразу нескольким целям, разделенным оператором |
error |
Позволяет необязательное присваивание ошибок, когда выражение справа может возвращать ошибки. Это обычно используется при вызове функций, которые могут возвращать ошибки. |
operator |
Оператор разделяет
|
expression |
Если Если |
Характеристики
Двойное присваивание
Оператор =
может использоваться для присваивания нескольким целям сразу. Двойное присваивание неприменимо, если используется присваивание ошибок.
Присваивание со слиянием
Оператор |=
обновляет поля в целевом объекте на основе содержимого объекта из expression
. При этом:
-
Поля, которые есть только в целевом объекте, остаются неизменными.
-
Поля, которые есть только во втором объекте, добавляются в целевой.
-
Если поле существует в обоих объектах, значение поля из
expression
заменяет значение из целевого объекта, вложенные структуры при этом не учитываются. Чтобы объединить при слиянии вложенные поля, используйте функциюmerge
с параметромdeep=true
.
Примеры
Присваивание пути
.message = "Hello, World!"
{ "message": "Hello, World!", }
Присваивание по вложенному пути
.parent.child = "Hello, World!"
Двойное присваивание
.first = .second = "Hello, World!"
{ "first": "Hello, World!", "second": "Hello, World!" }
Присваивание элементу массива
.array[1] = "Hello, World!"
Присваивание переменной
my_variable = "Hello, World!"
Hello, World!
Присваивание со слиянием объектов
my_variable = { "parent1": { "child1": 1, "child2": 2 }, "parent2": { "child3": 3 } } my_variable |= { "parent1": { "child2": 4, "child5": 5 } }
{ "parent1": { "child2": 4, "child5": 5 }, "parent2": { "child3": 3 } }
Присваивание с возможностью ошибки (успех)
.parsed, .err = parse_json("{\"Hello\": \"World!\"}")
{ "parsed": { "Hello": "World!" } }
Присваивание с возможностью ошибки (ошибка)
.parsed, .err = parse_json("malformed")
{ "err": "malformed" }
Арифметическое выражение
Арифметическое выражение выполняет операцию над двумя выражениями (операндами) согласно оператору.
Хотя арифметическое выражение обычно применяется к числам, его можно и с другими типами, такими как строки.
Синтаксис
expression ~ (operator ~ expression)+
Элемент | Описание |
---|---|
expression |
Выражение может быть любым выражением, которое возвращает тип, допустимый для оператора. |
operator |
Оператор определяет операцию, выполняемую над операндами слева и справа. Существующие операторы:
|
Характеристики
Арифметические операции над числами разных типов возвращают числа с плавающей точкой.
Действует стандартный приоритет операций: умножение и деление выполняются до сложения и вычитания. Для изменения приоритета используются скобки.
Примеры
Сложение целых чисел
1 + 1
2
Сложение чисел с плавающей точкой
0.1 + 0.2
0.30000000000000004
Некоторые десятичные дроби не могут быть точно представлены в двоичном виде, что приводит к небольшим неточностям в вычислениях (например, 0.1 + 0.2 != 0.3 ).
|
Сложение чисел разных типов
1 + 1.0
2
Сложение строк
"Hello" + ", " + "World!"
Hello, World!
Вычитание целых чисел
2 - 1
1
Вычитание чисел с плавающей точкой
2.0 - 1.0
1
Вычитание чисел разного типа
2.0 - 1
1
Перемножение целых чисел
2 * 1
2
Перемножение чисел с плавающей точкой
2.0 * 1.0
2
Перемножение чисел разного типа
2.0 * 1
2
Умножение строки на число
"строка" * 2
"строкастрока"
Деление целых чисел
2 / 1
2
Деление чисел с плавающей точкой
2.0 / 1.0
2
Деление чисел разных типов
2.0 / 1
2
Стандартный приоритет операций
5 + 6 × 9 - 7
52
Задание приоритета с помощью скобок
(5 + 6) × (9 - 7)
22
Для нахождения остатка используйте функцию Пример 114. Программа VRL
mod(3, 2) Пример 115. Результат
1 |
Сравнение
Выражение сравнения сравнивает два выражения (операнда) и возвращает логическое значение в соответствии с оператором.
Синтаксис
expression ~ operator ~ expression
Элемент | Описание |
---|---|
expression |
Операнд может быть любым выражением, которое возвращает тип, допустимый для оператора. |
operator |
Оператор определяет операцию, выполняемую над операндами слева и справа:
|
Характеристики
Равенство и неравенство
Операторы ==
и !=
предназначены для сравнения между собой любых значений. Числовые значения разных типов могут быть равными, другие значения считаются равными, только если относятся к одному типу.
Сравнение порядка
Операторы сравнения >
, <
, >=
и <=
применимы только к числам, строкам и меткам времени.
При сравнении строк используется лексикографический порядок, где символы сравниваются последовательно, на основе их номеров в таблице Unicode.
При сравнении меток времени большими считаются метки более поздней даты.
Примеры
Равенство чисел
1 == 1.0
true
Неравенство чисел
2 * 2 != 5
true
Больше или равно
2 >= 2.0
true
Больше
2 > 1
true
Меньше или равно
2.0 <= 2
true
Меньше
1 < 2
true
Сравнение временных меток
t'2024-04-04T22:22:22.234142+01:00' > t'2024-04-04T22:22:22.234142+04:00'
true
Сравнение строк
"ё" > "я"
true
Сравнение объектов
{"key1": "value1", "key2": "value2"} == {"key2": "value2", "key1": "value1"}
true
Сравнение пустых значений
null == null
true
Сравнение значений разных типов
2 == "2"
false
Логическое выражение
Выражение логического типа сравнивает два выражения (операнды), прекращая вычисление на последнем выражении, вычисленном в соответствии с оператором.
Синтаксис
operator ~ expression
expression ~ operator ~ expression
Элемент | Описание |
---|---|
expression |
Операнд может быть любым выражением, которое возвращает допустимый тип, определенный оператором. |
operator |
Оператор определяет операцию, выполняемую над операндами:
|
Примеры
AND
true && true
true
OR с логическим значением
false || "foo"
foo
OR с пустым значением
null || "foo"
foo
NOT
!false
true
Вызов функции
Выражение вызова функции вызывает встроенные функции VRL.
Синтаксис
function ~ abort? ~ "(" ~ arguments? ~ ")" ~ closure?
Элемент синтаксиса | Значение |
---|---|
function |
Имя встроенной функции. |
abort |
Прерывание — литерал
В противном случае ошибки должны обрабатываться:
Отсутствие обработки ошибок от функций, которые могут возвращать ошибку, приводит к ошибкам на этапе компиляции. Смотрите Справочник ошибок VRL для дополнительной информации. |
arguments |
Выражения, разделенные запятыми, которые могут дополнительно предваряться документированным именем. |
closure |
Замыкание — необязательный фрагмент кода, разрешенный вызовом функции. Замыкание применяется преимущественно в функциях, выполняющих итерации по коллекциям. Пример синтаксиса:
|
Примеры
Позиционный вызов функции
split("hello, world!", ", ")
[ "hello", "world!" ]
Вызов функции с именованными аргументами (упорядоченными)
split("hello, world!", pattern: ", ")
[ "hello", "world!" ]
Вызов функции с именованными аргументами (неупорядоченными)
split(pattern: ", ", value: "hello, world!")
[ "hello", "world!" ]
Объединение
Выражение объединения состоит из нескольких выражений (операндов), разделенных оператором объединения ??
. Логика объединения позволяет выбирать из списка выражений первое значение, которое соответствует заданному условию.
Оператор ??
полезен при обработке ошибок, так как позволяет задавать альтернативные способы обработки данных.
Синтаксис
expression ~ (operator ~ expression)+
Элемент | Описание |
---|---|
expression |
Операнд может быть любым выражением. |
operator |
Оператор разделяет два или более выражения. |
Примеры
Объединение при ошибках
parse_syslog("не Syslog") ?? parse_common_log("не Common Log Format") ?? "malformed"
malformed
Условие
Выражение условия (if) определяет условное выполнение двух ветвей в зависимости от значения логического выражения. Если логическое выражение оценивается как истинное (true
), выполняется ветвь "if". В противном случае выполняется ветвь "else", если она присутствует.
Синтаксис
"if" ~ predicate ~ block ~ ("else if" ~ predicate ~ block)* ~ ("else" ~ block)?
Элемент | Описание |
---|---|
predicate |
Предикат должен быть выражением, которое приводится к значению логического типа. Если логическое значение не возвращается, возникает ошибка на этапе компиляции. Предикат может содержать несколько выражений. Несколько предикатов выражений должны быть заключены в скобки. Выражения должны быть разделены точкой с запятой ( |
Примеры
Условие if true
if true { "Hello, World!" }
Hello, World!
Условие if false
if false { # not evaluated null }
null
Условие if/else
if false { # not evaluated null } else { "Hello, World!" }
Hello, World!
Условие if … else if … else
if false { # not evaluated null } else if false { # not evaluated null } else { "Hello, World!" }
Hello, World!
Многострочное выражение
x = 3 if (x = x + 1; x == 5) { # not evaluated null } else if ( x = x + 1 x == 5 ) { "Hello, World!" }
Hello, World!
Блок
Выражение блока представляет собой последовательность одного или нескольких выражений, заключенных в фигурные скобки.
Блоки не могут быть пустыми. Сочетание фигурных скобок без содержимого ({}
) рассматривается как пустой объект.
Синтаксис
"{" ~ "NEWLINE"* ~ expressions ~ "NEWLINE"* ~ "}"
Элемент | Описание |
---|---|
function |
Имя встроенной функции. |
expressions |
Одно или несколько выражений. |
Примеры
Простой блок
{ message = "{\"Hello\": \"World!\"}" parse_json!(message) }
{ "Hello": "World!" }
Присваивание в блоке
.structured = { message = "{\"Hello\": \"World!\"}" parse_json!(message) }
Прерывание
Выражение abort
приводит к завершению программы VRL, прерывая любые изменения, вносимые в событие.
Синтаксис
abort ~ message?
Элемент | Описание |
---|---|
message |
Необязательное отладочное сообщение, которое может быть использовано в диагностических целях и включается в метаданные события, отброшенного при преобразовании |
Примеры
Игнорирование недопустимых событий
{ "message": "hello world" }
if contains(string!(.message), "hello") { abort } .message = "not hello world"
{ message": "hello world" }