知っていて当たり前-18　正規表現が使える関数

# 知っていて当たり前-18　正規表現が使える関数

以下の関数は「正規表現が使える」のであるが，関数によっては「普通の文字列」も使える。

正規表現文字列は `r"文字列"` のように文字列の前に `r` をつけて表す。

また，普通の文字列が使えない関数もあるが，普通の文字列の前に `r` をつけて指定すればよい。

## 1.　マッチ `match()`

正規表現文字列しか使えない。

戻り値は，マッチした場合は RegexMatch object，マッチしなかった場合は `nothing` を返す。

まずは `match()` の結果が `nothing` かどうかを `isnothing()` で確認するのが第一段階。`nothing` の場合はそれでお終い。


```julia
regex = r"abc"
m = match(regex, "I love Halloween!")
isnothing(m)
```




    true




```julia
m = match(r"[0-9]", "I love Halloween!")
isnothing(m)
```




    true




```julia
regex = r"H.*w"
m = match(regex, "I love Halloween!")
isnothing(m)
```




    false



マッチした場合は，`.match` で一致した文字列, `.offset` で一致した位置を取得できる。


```julia
m.match, m.offset
```




    ("Hallow", 8)



検索を開始する位置を第 3 引数で指定することができる。


```julia
m = match(r"o", "I love Halloween!", 5)
isnothing(m)
```




    false




```julia
m.match, m.offset # 5文字目から始めると 12 文字目の "o" にマッチする
```




    ("o", 12)



## 2.　サブストリング，マッチ `occursin()`

第 1 引数が普通の文字列ならば，第 2 引数の文字列のサブストリングかどうか(文字列が含まれるか）を返す。

第 1 引数が正規表現文字列ならば，第 2 引数の文字列にマッチするかどうかを返す。

第 2 引数はベクトルでもよい。この場合は，それぞれの要素が第 1 引数を含むかどうかの論理値（true/false) を返す。


```julia
occursin("ab", "fabric")
```




    true




```julia
occursin("abc", "fabric")
```




    false




```julia
occursin(r"ab.*c", "fabric")
```




    true




```julia
occursin.("ab", ["fabric", "non"])
```




    2-element BitVector:
     1
     0



## 3.　サブストリング，マッチ `contains()`

引数の位置が逆であるが， `occursin()` と同じである。

第 1 引数はベクトルでもよい。この場合は，それぞれの要素が第 2 引数を含むかどうかの論理値（true/false) を返す。


```julia
contains("fabric", "ab") # R の grepl
```




    true




```julia
contains.(["fabric", "non"], "ab") # R の grepl # Boolean を返す
```




    2-element BitVector:
     1
     0




```julia
contains("about", r"a.*o")
```




    true



## 4.　最初の一致 `findfirst()`

第 1 引数が第 2 引数中に存在するかどうか一致する位置を返す。

複数ある場合は最初の一致する位置を返す。


```julia
findfirst(r"ab", "hj ab jkabs jhjhk ab")
```




    4:5




```julia
findfirst("ab", "hj ab jkabs jhjhk ab")
```




    4:5



## 5.　最後の一致 `findlast()`


```julia
findlast("ab", "hj ab jkabs jhjhk abff iui")
```




    19:20



## 6.　すべての一致 `findall()`


```julia
findall(r"ab", "hj ab jkabs jhjhk abff iui")
```




    3-element Vector{UnitRange{Int64}}:
     4:5
     9:10
     19:20




```julia
txt = "queen quit quickly"
[txt[s] for s in findall(r"qu.", txt)]
```




    3-element Vector{String}:
     "que"
     "qui"
     "qui"



## 7.　すべてのマッチ `eachmatch()`

すべてのマッチに対して一致したもののイテレータを返す。


```julia
text="abcdefg"
collect(eachmatch(r"qu.", "queen quit quickly"))
```




    3-element Vector{RegexMatch}:
     RegexMatch("que")
     RegexMatch("qui")
     RegexMatch("qui")




```julia
a = [s for s in eachmatch(r"qu.", "queen quit quickly")];
a
```




    3-element Vector{RegexMatch}:
     RegexMatch("que")
     RegexMatch("qui")
     RegexMatch("qui")



## 8.　文字列の置換 `replace()`

一致した文字列を別の文字列に置き換える。1 つの関数中で複数の置き換えを指定できる。

置き換える回数を指定できる。


```julia
replace("abcdefabcdefababababa", "ab"=>"@@")
```




    "@@cdef@@cdef@@@@@@@@a"




```julia
replace("abcdefabcdefababababa", "ab"=>"@@", count=2)
```




    "@@cdef@@cdefababababa"




```julia
replace("a, b:, c? d!", r"[!?':,,.]" => "")
```




    "a b c d"

大文字/小文字変換は簡単にできる。

```Julia
replace("abcdefabcdefababababa", r"[a-z]" => uppercase)
```
    "ABCDEFABCDEFABABABABA"

```Julia
replace("ABCDEFABCDEFABABABABA", r"[AB]" => lowercase)
```
    "abCDEFabCDEFababababa"

`s"新文字列"` は `r"旧文字列"` を引用する場合に使う。


```julia
replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1")
```




    "second first"




```julia
replace("The quick foxes run quickly.", r"fox(es)?" => s"bus\1")
```




    "The quick buses run quickly."