正则表达式(regex)是 Elixir 中处理字符串的强大工具。Elixir 中的正则表达式遵循 PCRE 规范(Perl Compatible Regular Expressions,即 Perl 兼容正则表达式)。用于表示正则表达式含义的字符串模式会先被编译,然后用于匹配整个字符串或其中的一部分。
在 Elixir 中,创建正则表达式最常见的方式是使用~r sigil。Sigil 为 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 - 启用\p之类的 Unicode 专用模式,并让\w等字符类也能匹配 Unicode
"ö" =~ ~r/^\w$/
# => false
"ö" =~ ~r/^\w$/u
# => true
dotall、multiline、extended、firstline、ungreedy因为~r sigil 是"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!"