正規表現 #
文字列がパターンにマッチするか判定する #
単純なパターンマッチには func MatchString(pattern string, s string) (matched bool, err error)
が使える。
文字列 s がパターン pattern にマッチしたら matched が true になる。
package main
import (
"fmt"
"regexp"
)
func main() {
// マッチする場合
ok, err := regexp.MatchString(`^h`, "hello world")
fmt.Println(ok, err) // == true <nil>
// マッチしない場合
ok, err = regexp.MatchString(`^h`, "Hello world")
fmt.Println(ok, err) // == false <nil>
// 正規表現が不正な場合はエラーが返る
ok, err = regexp.MatchString(`(aaa`, "hello world")
fmt.Println(ok, err) // == false error parsing regexp: missing closing ): `(aaa`
}
参考ドキュメント: regexp
正規表現オブジェクトを初期化する #
パターンマッチを繰り返し行う場合やパターンによる置換やマッチした文字列の取得など行う場合は、正規表現パターンをコンパイルしてオブジェクト化して利用する。
正規表現オブジェクトの初期化には func Compile(expr string) (*Regexp, error)
を使う。
package main
import (
"fmt"
"regexp"
)
func main() {
// 初期化
re, err := regexp.Compile(`a+`)
fmt.Println(re, err) // == a+ <nil>
// パターンマッチは `func (re *Regexp) Match(b []byte) bool` で行う
fmt.Println(re.MatchString("aaa")) // == true
fmt.Println(re.MatchString("bbb")) // == false
// 正規表現が不正な場合はエラーが返る
re, err = regexp.Compile(`(b`)
fmt.Println(re, err) // == <nil> error parsing regexp: missing closing ): `(b`
// 使い捨てのコードやサンプルコードなどでエラー処理が不要な場合は `func MustCompile(str string) *Regexp` で正規表現オブジェクトの初期化をすることもできる
// MustCompile は error を返さず手軽に扱えるが、エラーになった場合に panic を発生させるので実用には向かない
re = regexp.MustCompile(`(c`) // => panic: regexp: Compile(`(c`): error parsing regexp: missing closing ): `(c`
}
参考ドキュメント: regexp
パターンにマッチした文字列を取得する #
パターンにマッチした文字列を取得したい場合は func (re *Regexp) FindAllString(s string, n int) []string
を使う。
引数 n はマッチさせる回数で -1 を指定すると回数無制限で全ての文字をマッチさせる。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`a+`)
fmt.Println(re.FindAllString("abaabb", -1)) // == [a aa]
fmt.Println(re.FindAllString("abaabbaaabbb", -1)) // == [a aa aaa aaaa]
fmt.Println(re.FindAllString("ccc", -1)) // == []
}
参考ドキュメント: regexp
パターン中のキャプチャブループにマッチした文字列を取得する #
パターン中のキャプチャグループにマッチした文字列を取得したい場合は func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
を使う。
引数 n はマッチさせる回数で -1 を指定すると回数無制限で全ての文字をマッチさせる。
matched は [[パターン全体にマッチした文字列, キャプチャブループにマッチした文字列...]...]
という構造になる。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`a(a*)`)
matched := re.FindAllStringSubmatch("abaabbaaabbb", -1)
fmt.Printf("%#v\n", matched) // == [][]string{[]string{"a", ""}, []string{"aa", "a"}}
// マッチしない場合は nil になる
fmt.Printf("%#v\n", re.FindAllStringSubmatch("ccc", -1)) // == [][]string(nil)
}
参考ドキュメント: regexp
パターンにマッチした文字列を置換する #
パターンマッチした文字列を置換したい場合は func (re *Regexp) ReplaceAllString(src, repl string) string
を使う。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`a+`)
replaced := re.ReplaceAllString("abaabbaaabbb", "A")
fmt.Println(replaced) // == AbAbbAbbb
}
参考ドキュメント: regexp
区切り文字をパターンで指定して文字列を分割する #
文字列をパターンで分割する場合は func (re *Regexp) Split(s string, n int) []string
を使う。
n はマッチ回数で -1 にすれば無制限になる。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`a+`)
list := re.Split("abaabbaaabbb", -1)
fmt.Printf("%#v", list) // == []string{"", "b", "bb", "bbb"}
}
参考ドキュメント: regexp