Elixirでは正規表現を使用する際に、Regex
モジュールを使用します。
Regex
はPCRE(Perl Compatible Regular Expressions) に基いています。
正規表現は ~r/pattern/
で扱われます。
optionの説明はDocumentにまかせて、
各種ファンクションを使ってみようと思います。
実行しているversionは1.2.0
です。
compile(source, options \ "")
source
にはbinaryを指定します。
Elixirでbinaryとは""で囲った文字列のことです。
iex(3)> Regex.compile("AbC")
{:ok, ~r/AbC/}
iex(4)> {:ok, pattern} = Regex.compile("AbC")
{:ok, ~r/AbC/}
iex(8)> {:ok, pattern} = Regex.compile("AbC", [:unicode])
{:ok, ~r/AbC/}
```
optionsはatomの配列を渡します。
optionsの一覧はこれです。
compile!(source, options \ "")
こちらはエラー時に、Regex.CompileError
というExceptionを吐いて失敗します。
escape(string)
compile時はsource
といっていたのにこちらはstring
同じだと思うけど、違うのだろうか・・。
iex(15)> Regex.escape("Ab.C")
"Ab\\.C"
文字列を渡した際にエスケープ対象の文字列があったらエスケープされます。
match?(regex, string)
正規表現にマッチしているかを判定します。
compileで作成したpatternか、~rのsigilでパターンでregexを指定します。
iex(16)> Regex.match?(pattern, "AbC")
true
iex(17)> Regex.match?(~r/AbC/, "AbC")
true
named_captures(regex, string, options \ [])
正規表現にマッチした名前付きキャプチャをマップで返します。
optionsに、%{ return: :index }
を渡すことで、戻り値を文字列ではなく、
stringのindexで返すこともできます。
iex(19)> Regex.named_captures(~r/A(?<hoge>b)C/, "AbC")
%{"hoge" => "b"}
iex(20)> Regex.named_captures(~r/A(?<hoge>b)C/, "AbC", [return: :index])
%{"hoge" => {1, 1}}
names(regex)
Regex中の名前付きキャプチャの名前を返します。
iex(21)> Regex.names(~r/A(?<hoge>b)C/)
["hoge"]
opts(regex)
Regexのoptionを返します。
iex(24)> Regex.opts(~r/A(?<hoge>b)C/mi)
"mi"
re_pattern(regex)
re_patternを返します。
iex(26)> Regex.re_pattern(~r/AbC/)
{:re_pattern, 0, 0, 0,
<<69, 82, 67, 80, 69, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 65, 0, 67, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...>>}
re_patternはおそらく erlangの :re モジュールで使用する regex のことですね。
:reモジュールのcompileファンクションを使用すると同じ結果が得られます。
iex(27)> :re.compile("AbC")
{:ok,
{:re_pattern, 0, 0, 0,
<<69, 82, 67, 80, 69, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 65, 0, 67, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...>>}}
regex?(term)
与えられた引数がRegexパターンかどうかを判定します。
iex(28)> Regex.regex?(~r/Abc/)
true
replace(regex, string, replacement, options \ [])
stringからregexにマッチした部分をreplacementに置き換えます。
iex(29)> Regex.replace(~r/Abc/, "Abc", "ABC")
"ABC"
## デフォルトではマッチが複数あった場合に全て置き換えます。
iex(30)> Regex.replace(~r/Abc/, "AbcTAbc", "ABC")
"ABCTABC"
## globalオプションにfalseを渡すことで1つめのマッチのみを置き換えられます。
iex(33)> Regex.replace(~r/Abc/, "AbcTAbc", "ABC", global: false)
"ABCTAbc"
## \\1 はマッチしたキャプチャ部分が取得できます。
iex(34)> Regex.replace(~r/a(b|d)c/, "abcadc", "[\\1]")
"[b][d]"
## \\0 はマッチ全体になります。
iex(35)> Regex.replace(~r/a(b|d)c/, "abcadc", "[\\0]")
"[abc][adc]"
## キャプチャと文字列を組み合わせる場合は \\g{N} を使用します。
iex(40)> Regex.replace(~r/\.(\d)$/, "500.5", ".\\g{1}0")
"500.50"
## replacementは関数を指定することもできます。
iex(41)> Regex.replace(~r/a(b|d)c/, "abcadc", fn _, x -> "[#{x}]" end)
"[b][d]"
## 第一引数には、マッチ全体が与えられます。
iex(42)> Regex.replace(~r/a(b|d)c/, "abcadc", fn all, x -> "[#{all}]" end)
"[abc][adc]"
run(regex, string, options \ [])
最初にマッチする文字列があるまでマッチを続けます。
マッチしなかった場合は nil を返します。
iex(43)> Regex.run(~r/Abc/, "AbcAbc")
["Abc"]
iex(44)> Regex.run(~r/Abc/, "AbC")
nil
# キャプチャがある場合はそれも返ります。
iex(46)> Regex.run(~r/A(b)c/, "Abc")
["Abc", "b"]
# returnオプションにindexを指定すると、indexで返却されます。
iex(47)> Regex.run(~r/A(b)c/, "Abc", [return: :index])
[{0, 3}, {1, 1}]
scan(regex, string, options \ [])
全てのマッチを集める、runというイメージです。
iex(49)> Regex.scan(~r/c(d|e)/, "abcd abce")
[["cd", "d"], ["ce", "e"]]
source(regex)
compileファンクションの逆。
regexをバイナリにします。
iex(50)> Regex.source(~r/AbC/)
"AbC"
split(regex, string, options \ [])
stringをregexのパターンで分割します。
iex(51)> Regex.split(~r/-/, "a-b-c")
["a", "b", "c"]
## partsオプションを指定すると、指定した数に分割します。
iex(52)> Regex.split(~r/-/, "a-b-c", [parts: 2])
["a", "b-c"]
## trimオプションを指定すると、結果から、空文字列を除く。らしいがうまくいってない。
iex(54)> Regex.split(~r/-/, "a- b- c", trim: true)
["a", " b", " c"]
## キャプチャを分割パターンにする。
iex(58)> Regex.split(~r/a(?<hoge>b)c/, "abc", on: [:hoge])
["a", "c"]
おわり