Elixirで正規表現	


Elixirでは正規表現を使用する際に、`Regex`モジュールを使用します。

[Document](http://ns.maqcsa.org/elixir/docs/v1.2.0-rc.1/elixir/Regex.html)

`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(?<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"]
```

おわり