LoginSignup
24
18

More than 5 years have passed since last update.

Goの正規表現のよいところ

Posted at

Goの正規表現はRuss Coxさんの書いたre2が元になっている。re2はよくできた正規表現エンジンなのだけど、一つほかの正規表現エンジンに見られる機能が欠けている。バックリファレンスがないのだ。

ほかの正規表現エンジンではカッコでキャプチャした文字列を番号を指定して正規表現中でもう一度使うことができて、/(\w+) \1/というようなパターンを書くことができる。このパターンは(\w+)にマッチするもの(たとえば単語)に続いて空白文字列があって、さらに()の内容と同じ文字列があること、という条件になる。たとえばこれは"foo foo"はこのパターンにマッチするけど(最初の"foo"が繰り返しているので)、"foo bar"はマッチしない("foo"と"bar"は違うので)というわけだ。

バックリファレンスがないのは欠点に思えるが(実際に不便なときもないわけではないが)、しかしこれはGoの正規表現エンジンがほかの正規表現エンジンとは異なるアルゴリズムを採用しているために生じる副作用である。この機能だけを外すことによって得るものは大きいので、Goの正規表現エンジンは全体的にはほかの正規表現エンジンより大変よくできているといってよいと思う。

re2あるいはGoの正規表現エンジンの一番大きな特長は、入力が長くなったぶんだけしか(リニアにしか)実行時間が長くならないことだ。普通のことだと思うかもしれないが、他の正規表現エンジンでは、入力長に対して指数的に実行時間が長くなりえる。たとえばxxxxxxxxxxxxxxxという文字列に対して/(x+x+)+y/をマッチさせてみるとまるでハングアップしたみたいになる正規表現エンジンというのは特別なものではない。

そういった正規表現エンジンでは、正規表現とマッチ対象の文字列の両方を与えられるUIがあったとすると、簡単にサーバプロセスをハングアップさせることができてしまう。

re2で使われているアルゴリズムはこのような性質は持っていないのでこの点は安全だ。動作が単純で予測しやすいのはよいことだ。

24
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
18