プログラミングで複雑なルールによる入力チェックや、文字列置換を行いたい時に正規表現を使えると非常に便利です。
複雑な入力チェックの処理をいくつも記述すると分かりづらいコードで、不具合の原因となる場合もあります。
正規表現を用いるとシンプルな記述方法で、簡潔なロジックで表すことができます。
その一方で、正規表現自体の記述方法はルールがたくさんあり、すべてを覚えるのは困難です。
必要な時に調べれば良いので、すべてを覚える必要はないと思いますが、どんなことができるのかは知っておく必要があります。
そこで本記事では、Goの正規表現についての記述方法やできることについてまとめます。
プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。
記載しているプログラムは、go1.15.2を使って動作確認をしています。
Goの正規表現
Goの正規表現として以下の内容を採り上げます。
- 正規表現の作成方法
- 正規表現による文字列チェック
- 正規表現による文字列置換
- 正規表現による文字列抽出
- 正規表現のエスケープ
正規表現の作成方法
Goで正規表現を扱うには、regexpパッケージ を使用します。
regexpパッケージを使用するには、importが必要となります。
正規表現を作成するには、regexp.MustCompileに正規表現の文字列を指定します。
正規表現を指定する文字列は、ダブルクォーテーションで囲む方法と、バッククォーテーションで囲む方法があります。
- ダブルクォーテーションで囲む:バックスラッシュをさらにエスケープする必要がある
- バッククォーテーションで囲む:正規表現で表したい文字列のまま表現することができる
そのため基本的は、バッククォーテーションで囲む方法をおすすめします。
本記事でもバッククォーテーションで囲む方法で解説します。
正規表現にはたくさんの特殊文字やオプションがありますが、詳細はドキュメントをご参照ください。
正規表現による文字列チェック
正規表現による文字列チェックは、regexpパッケージのMatchString、FindString、FindStringIndex、FindAllString等を使います。
上記以外にも様々な用途に応じた関数が用意されています。
MatchString関数
MatchString関数は、指定した文字列が正規表現にマッチするはtrueを返し、マッチしない場合はfalseを返します。
str = "Hello Go!!" regex = regexp.MustCompile(`Go`) fmt.Println(regex.MatchString(str)) // -> true
正規表現にはオプションを付けることができます。
よく使われるのは、大文字小文字を区別せずにマッチさせるオプションの i です。
str = "Hello Go!!" regex = regexp.MustCompile(`(?i)go`) fmt.Println(regex.MatchString(str)) // -> true
FindString関数
FindString関数は、正規表現に最初にマッチした文字列を返します。
マッチしない場合は空文字列を返します。
str = "Hello Go!!" regex = regexp.MustCompile(`Go`) fmt.Println(regex.FindString(str)) // -> Go
FindStringIndex関数
FindStringIndex関数は、正規表現に最初にマッチした文字列の位置の先頭と末尾のインデックスを配列で返します。
先頭から一致する場合は0を返します。
マッチしない場合はnilを返します。
str = "Hello Go!!" regex = regexp.MustCompile(`Go`) fmt.Println(regex.FindStringIndex(str)) // -> [6 8]
FindAllString関数
FindAllString関数は、正規表現にマッチしたすべての文字列を配列で返します。
マッチしない場合はnilを返します。
第2引数でマッチさせる上限数を指定します。負数を指定した場合はすべてに一致させます。
str = "Hello Go!!" regex = regexp.MustCompile(`Go`) fmt.Println(regex.FindAllString(str, -1)) // -> [Go]
正規表現による文字列置換
正規表現による文字列置換は、regexpパッケージのReplaceAllStringを使います。
ReplaceAllString関数は、正規表現にマッチする文字列をすべて置換します。
str = "Hello Go!!" regex = regexp.MustCompile(`\w`) rep = "*" fmt.Println(regex.ReplaceAllString(str, rep)) // -> ***** **!!
上記のプログラムでは英字をアスタリスクに置換しています。
正規表現による文字列抽出
正規表現で指定した部分を文字列から抽出するには、抽出したいパターンに括弧を含めて指定します。
ReplaceAllString関数で抽出した文字列を使って置換をする場合は、抽出した文字列を$1、$2を使って取得します。
str = "Hello Go!!" regex = regexp.MustCompile(`(\w+)\s(\w+)`) fmt.Println(regex.ReplaceAllString(str, "$2 $1")) // -> Go Hello!!
文字列の抽出のみ行う場合は、FindStringSubmatch関数を使います。
抽出した文字列が配列で返されます。
インデックス0がマッチした文字列全体、インデックス1が1つ目に抽出した結果、インデックス2が2つ目に抽出した結果となります。
str = "Hello Go!!" regex = regexp.MustCompile(`(\w+)\s(\w+)`) a := regex.FindStringSubmatch(str) fmt.Println(a[0]) // -> Hello Go fmt.Println(a[1]) // -> Hello fmt.Println(a[2]) // -> Go
正規表現のエスケープ
正規表現においてピリオドやプラス、アスタリスクなどの記号は、特殊文字として定義されている文字です。
これらを文字列に含んでいる場合の正規表現を作成する場合は、特殊文字として扱われないようにエスケープする必要があります。
エスケープは、特殊文字の直前にバックスラッシュを付けます。
str = "Hello+Go." regex = regexp.MustCompile(`\w+\+\w+\.`) fmt.Println(regex.MatchString(str)) // -> true
上記のプログラムでは、プラスとピリオドの直前にバックスラッシュを入れてエスケープした正規表現を作成しています。
また、エスケープが必要な文字が含まれている文字列全体をプログラムによってエスケープしたい場合は、QuoteMeta関数でエスケープ処理が行なえます。
str = "Hello+Go." regex = regexp.MustCompile(`\w+\+\w+\.`) r := regexp.QuoteMeta(str) fmt.Println(r) // -> Hello\+Go\. regex = regexp.MustCompile(r) fmt.Println(regex.MatchString(str)) // -> true
正規表現はプログラム外でも役に立つ
正規表現はプログラムをシンプルにしてくれる便利なものですが、プログラム外でも役に立つことがあります。
エディタを使って文章を書いている際に、文字列の検索や置換をしたくなった場合に、正規表現で指定することが可能なエディタもあります。
Linuxのコマンドでも正規表現を使えるコマンドがたくさんあります。
Excelの関数などでも正規表現を使うことができます。
正規表現で書いてみたけど、思うようにマッチしないという場合には、正規表現チェッカーというツールで分かりやすく一致部分を表現してくれるツールもありますので活用してみてください。
正規表現は記述方法が難しいのですが、書けると非常に効率を上げてくれる手段になります。
サラッと正規表現を書ける人はカッコいいですよね。
今回はGoの正規表現についてまとめました。
以上、参考になれば幸いです。
コメント