Go 言語で正規表現を扱うときの関数

Today I Learned

Go 言語で正規表現を扱うときは、regexp パッケージをインポートする。

正規表現のパターンを定義する

正規表現のパターンを初期化して解析するには、Compile()MustCompile() を使う。
MustCompile() の場合は、正しい文法でなければ panic になる。
JavaScript でいうと、MustCompile()RegExp コンストラクタ に近いのかな。

import (
    "fmt"
    "regexp"
)

func main() {
    re, _ := regexp.Compile(`ab+c`)
    fmt.Println(re) // ab+c

    re2 := regexp.MustCompile(`ab+c`)
    fmt.Println(re2) // ab+c
}

文字列を検索する

関数名に String を含まない場合は引数に byte 配列の参照を渡し、 関数名に String を含む場合、引数は文字列を渡す。
以降は、引数が文字列の関数を挙げる。

また、関数名に All がついていると、g フラグが付いていると同じ動きになる。
つまりパターンに一致する文字列を複数検出できる。
第 2 引数には取得するマッチ数を指定する。 -1 を指定するとマッチしたすべての文字列を返す。

パターンに一致する文字があるかどうかを調べる

  • MatchString():パターンに一致する文字列があれば true を返す。
import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    str := `123-456abc789-012`
    fmt.Println(re.MatchString(str)) // true
}

パターンに一致する文字列を取得する

  • FindString(): パターンに一致する最初の文字列を返す。
  • FindAllString():パターンに一致する文字列の配列を返す。
import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    str := `123abc435`
    fmt.Println(re.FindString(str)) // 123
    fmt.Println(re.FindAllString(str, -1)) // [123 435]
}

パターンに一致する文字列の位置を取得する

  • FindStringIndex(): パターンに一致する最初の文字列の始まりと終わりの位置を返す。
  • FindAllStringIndex():パターンに一致する文字列の始まりと終わりの位置の配列を返す。
import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    str := `123abc435`
    fmt.Println(re.FindStringIndex(str)) // [0 3]
    fmt.Println(re.FindAllString(str, -1))// [[0 3] [6 9]]
}

FindStringSubmatch() と FindAllStringSubmatch()

  • FindStringSubmatch():パターンに一致する最初の文字列の配列を返す。
    パターンでグルーピングしていると、次の値を返す。

    [マッチした全体の文字列, キャプチャした文字列1, キャプチャした文字列2, ... ]
    
  • FindAllStringSubmatch():パターンに一致する文字列の配列を返す。
    パターンでグルーピングしていると、次の値を返す。

    [
      [1番目にマッチした全体の文字列, キャプチャした文字列1, キャプチャした文字列2, ... ],
      [2番目にマッチした全体の文字列, キャプチャした文字列1, キャプチャした文字列2, ... ],
      ...
    ]
    
import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\d+)-(\d+)`)
    str := `123-456abc789-012`
    fmt.Println(re.FindStringSubmatch(str)) // [123-456 123 456]
    fmt.Println(re.FindAllStringSubmatch(str, -1)) // [[123-456 123 456] [789-012 789 012]]
}