Регулярні вирази (regex) - це потужний інструмент для роботи з рядками тексту (англ. string) в Elixir. Регулярні вирази в Elixir відповідають специфікації PCRE (Perl Compatible Regular Expressions). Шаблони рядків, які передають зміст регулярного виразу, спочатку компілюються, а потім використовуються для зіставлення з усім рядком тексту або його частиною.
У Elixir найчастіше регулярні вирази створюють за допомогою сигіла ~r. Сигіли дають синтаксичний цукор, тобто скорочення для типових завдань у Elixir. У цьому випадку ~r - скорочення для використання Regex.compile!/2.
Regex.compile!("test") == ~r/test/
# => true
Оператор =~/2 стає в пригоді, коли треба зіставити рядок тексту з регулярним виразом і отримати результат boolean.
"this is a test" =~ ~r/test/
# => true
\, наприклад ~r/\?/.\d, \w) дають змогу шаблону зіставлятися з діапазоном символів|) дають змогу шаблону зіставлятися з одним або іншим шаблоном{N, M}, *, ?) дають змогу шаблону зіставлятися із заданою кількістю повторюваних шаблонів()) дають змогу частинам шаблону працювати як одне цілеРегулярні вирази також стають у пригоді, коли треба видобути частину рядка тексту. Це називається захопленням. Щоб захопити частину рядка тексту, створімо групу (()) для тієї частини, яку ми хочемо захопити, і скористаймося Regex.run.
Regex.run(~r/Weight: (\d*)g/, "Weight: 150g")
# => ["Weight: 150g", "150"]
Захоплення нумеруються (починаючи з 1), і їх також можна використовувати в результаті, коли ми замінюємо частини рядка тексту за допомогою регулярного виразу:
Regex.replace(~r/Weight: (\d*)g/, "Weight: 150g", "Gewicht: \\1g")
# => "Gewicht: 150g"
Захопленням також можна дати імена, додавши ?<name> після відкритої дужки. Скористаймося Regex.named_captures/3, щоб отримати словник з іменованими захопленнями.
Regex.named_captures(~r/Weight: (?<weight>\d*)g/, "Weight: 150g")
# => %{"weight" => "150"}
Поведінку регулярного виразу можна змінити, додавши спеціальні прапорці в кінці регулярного виразу, наприклад ~r/test/i.
caseless i - нечутливий до регістру
"A" =~ ~r/a/
# => false
"A" =~ ~r/a/i
# => true
unicode u - уможливлює шаблони, специфічні для Unicode, як-от \p, і змушує класи символів, як-от \w тощо, також зіставлятися з Unicode
"ö" =~ ~r/^\w$/
# => false
"ö" =~ ~r/^\w$/u
# => true
dotall, multiline, extended, firstline, ungreedyОскільки сигіл ~r - це скорочення для "pattern" |> Regex.escape() |> Regex.compile!(), ми також можемо скористатися інтерполяцією рядків тексту, щоб динамічно побудувати шаблон регулярного виразу:
anchor = "$"
regex = ~r/end of the line#{anchor}/
"end of the line?" =~ regex
# => false
"end of the line" =~ regex
# => true
String
Хоч регулярні вирази й потужні, користуватися ними не завжди розважливо:
Як правило, краще за можливості використовувати функції з модуля String.
# Don't use regular expressions to check a suffix:
if "YELLING!" =~ ~r/!$/, do: "Whoa, chill out!"
# Use a string function:
if String.ends_with?("YELLING!", "!"), do: "Whoa, chill out!"