Треки
/
Elixir
Elixir
/
Салабус
/
Регулярні вирази
Ре

Регулярні вирази у Elixir

24 вправи

Про концепцію Регулярні вирази

Регулярні вирази (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!"
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Регулярні вирази

Практика заблокована

Розблокуйте ще 10 вправ, щоб практикувати концепцію Регулярні вирази