« ^ »

Golangで正規表現を使用する

所要時間: 約 2分

regexpが正規表現のために標準ライブラリとして用意されている。

シンプルな使い方

コマンドラインの最初の引数の文字列がコード内に埋め込まれた正規表現にマッチするかどうかを表示する、 簡単なプログラムを作成した。 コード内に埋め込まれた正規表現は、文字列の先頭がTESTで始まるかどうかを判定する。

package main

import (
	"fmt"
	"os"
	"regexp"
)

func main() {
	t := os.Args[1]

	r := regexp.MustCompile("^TEST.*")
	m := r.MatchString(t)
	if m == false {
		fmt.Println("Unmatch!!")
		return 
	}
	fmt.Println("Match!!")
}

マッチする例

コマンドの引数に TESTING を渡す。 当然 TEST で始まっているためマッチする。

go run simple.go TESTING
Match!!

マッチしない例

次に、コマンドの引数に foo を渡す。 当然 TEST で始まっていないためマッチしない。

go run simple.go foo
Unmatch!!

グルーピング

正規表現でマッチした文字列の一部を取得する。 例えば This is a pen. という文字列を考える。 このpenの部分には他の単語が指定される可能性があるとする。 つまり This is a apple. かもしれないし This is a bread. かもしれない。 問題を簡単にするためにpenにあたる部分には小文字のアルファベットのみが指定されるものとする。

こういったケースでは正規表現のグルーピング機能を使う。

package main

import (
	"fmt"
	"os"
	"regexp"
)

func main() {
	t := os.Args[1]

	r := regexp.MustCompile("^This is a (?P<something>[a-z]+)\\.$")
	m := r.FindStringSubmatch(t)
	if m == nil {
		fmt.Println("Unmatch!!")
		return
	}
	fmt.Println("Match!!")
	fmt.Println(m[1])
}

先程とそれほど変りはない。コマンドの先頭の引数を取得してマッチするかを判定する。 マッチした場合、penの部分には何が指定されていたのかを表示する。

マッチする例

まずは通常の 'This is a pen.' を引数に渡す。 空白を含む文字列を一つの引数として渡す場合、クォートまたはダブルクォートで括る必要がある。 この例はマッチし pen が表示される。

go run group.go 'This is a pen.'
Match!!
pen

penの部分をcarに置き換えても同様にマッチする。

go run group.go 'This is a car.'
Match!!
car

マッチしない例

次にマッチしない例を試す。 まずは 'TESTING' を渡す。 もう全く異なる文字列であり、当然マッチしない。

go run group.go 'TESTING'
Unmatch!!

次に大文字のPENを指定する。 今回は正規表現で小文字アルファベットのみマッチするように指定しているためマッチしない。

go run group.go 'This is a PEN.'
Unmatch!!

同様に数字の1を指定してもマッチしない。

go run group.go 'This is a 1.'
Unmatch!!

p e n のように空白が含まれているものも、 空白が小文字アルファベットではないため当然マッチしない。

go run group.go 'This is a p e n.'
Unmatch!!

URLの一部を検出する

使用例としてURLのオリジンの指定よりも後の値を取得する。

package main

import (
	"fmt"
	"os"
	"regexp"
)

func main() {
	t := os.Args[1]

	r := regexp.MustCompile("^https?://[^/]+(?P<path>.*)$")
	m := r.FindStringSubmatch(t)
	if m == nil {
		fmt.Println("Unmatch!!")
		return
	}
	fmt.Println("Match!!")
	fmt.Println(m[1])
}

実行する。

go run match_url.go 'http://example.com/foo/bar/baz'
Match!!
/foo/bar/baz

取得できた。