Elixirで正規表現
Elixir の正規表現は Regexモジュール を使う。
仕事ではPHPを書くことが多い。PHPの正規表現は PCRE関数 が標準的だろう。普段使うPCRE関数をElixirのRegex で置き換えるとしたらどうなるのか?
比較の対象は preg-match と preg_replace の二つにする。理由は、その二つをよく使うので (その二つくらいしか使わないとも言う)。
preg_match と比べて
単純なマッチ
単純にマッチするかどうかを判定する場合, Regex.match?/2 を使う。
<?php echo preg_match('/foo/', 'foo'); // => 1
iex> Regex.match?(~r/foo/, "foo") true
名前なしキャプチャ
名前なしキャプチャを利用する場合, Regex.run/3 を使う。preg_match はキャプチャした結果は変数の参照を介して受け取る。Regex の場合 run/3 の返り値として受けとる。
一度マッチしたらそこで処理は打ち切られる。打ち切られたくない場合は Regex.scan/3 を使う (PHP なら preg_match_all)。
<?php preg_match('/c(d)/', 'abcd', $m); print_r($m); // => Array // ( // [0] => cd // [1] => d // )
iex> Regex.run(~r/c(d)/, "abcd") ["cd", "d"]
名前つきキャプチャ
名前つきキャプチャは Regex.named_captures/3。Regex.named_captures/3 はキャプチャされた部分のみの結果になる。
<?php preg_match('/c(?<foo>d)/', "abcd", $m); print_r($m); // => Array // ( // [0] => cd // [foo] => d // [1] => d // )
iex> Regex.named_captures(~r/c(?<foo>d)/, "abcd") %{"foo" => "d"}
preg_replace と比べて
Regex.replace で置換を行う。引数の順序が違うので慣れで書くと間違う。
<?php echo preg_replace('/b/', 'd', 'abc').PHP_EOL; // => adc echo preg_replace('/\.(\d)$/', '.${1}0', '500.5'); // => 500.50
iex> Regex.replace(~r/b/, "abc", "d") "adc" iex> Regex.replace(~r/\.(\d)$/, "500.5", ".\\g{1}0") "500.50"
感想
PHP でできていたことは Elixir でもできる(まあ、PCRE互換だし)。
PHPの場合はパラメータによって一つの関数の中で機能をon/offしたりする感じだけれど、Elixir は機能ごとに関数を用意する感じ。