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の一覧は[これ](http://erlang.org/doc/man/re.html#type-compile_option)です。
## 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(?b)C/, "AbC")
%{"hoge" => "b"}
iex(20)> Regex.named_captures(~r/A(?b)C/, "AbC", [return: :index])
%{"hoge" => {1, 1}}
## names(regex)
Regex中の名前付きキャプチャの名前を返します。
iex(21)> Regex.names(~r/A(?b)C/)
["hoge"]
## opts(regex)
Regexのoptionを返します。
iex(24)> Regex.opts(~r/A(?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(?b)c/, "abc", on: [:hoge])
["a", "c"]
おわり