2006-07-16

先読みの正規表現

Bayesian推定のプログラムを作っている途中で気が付いたこと。

ファイルをトラバースする際に、探索を打ち切るパス名を正規表現で表現したい。具体的には「パス要素がちょうど3で、第3要素が"image"ではない」パス名だけマッチさせたい。

で、最初は[^/]+/[^/]+/[^i][^m][^a][^g][^e].*かな?と思って試したんだけど、良く考えるとa/b/xxxがマッチしない(探索を打ち切れない)ので、これは間違い。

次に「幅ゼロの否定先読み」という難しい機能が使えるかなと思って[^/]+/[^/]+/(?!image)を指定したけど、何もマッチしない。

おかしいなあと思ってPerlの正規表現(Javaの正規表現はPerlの影響が大きいようだ)を調べてみると… うわ、よくある間違いだった… orz

上記の例だと、「imageが後続しない、第3要素が空の、3つのパス要素を持つパス」の意味になって、"aaa/bbb/"などにしかマッチしない。

正解は[^/]+/[^/]+/(?!image).+だった。しかし、Perl/Javaの正規表現は難しいなあ…

0 件のコメント: