正規表現をいじっていたらハマったのでメモ。
TL;DR
- 文字クラス(
[]
)でハイフン(-
)を指定しているつもりがちゃんと判定されない - 文字クラスの中でハイフンを指定するときは最初か最後にハイフンを置かないと範囲指定あつかいされてしまう。
文字クラス([]
)でハイフン(-
)を指定しているつもりがちゃんと判定されない
Makefile
の自己文書化をしていた。
上述のリンク先では以下のようなワンライナーが紹介されている。
このワンライナーでは、序盤の@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST)
部分でMakefile
内の対象行を拾って後続の処理を行なっている。
.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
私のMakefile
にはmake docker.run
などのようなドット(.
)を含むコマンド定義があったが、この正規表現にドットは含まれていない。
そのため、上記の正規表現中の^[a-zA-Z_-]
の部分を^[a-zA-Z_-\.]
と変更したところ、ハイフンを含む行がヒットしなくなってしまった。
文字クラスの中でハイフンを指定するときは最初か最後にハイフンを置かないと範囲指定扱いされてしまう。
\-
とエスケープをして^[a-zA-Z_\-\.]
のように書いても当然意味がなかった。結局検索して解決することができた。一次ソース(仕様)は見つけられなかった。(正規表現の仕様はWeb上には公開されていないのだろうか?)
- 正規表現 -ハイフン 判定
節タイトルの通り、文字クラスの中でハイフン(-
)を指定するときは最初か最後に指定しないといけないようだ。
^[a-zA-Z_-\.
を^[a-zA-Z_.\-]
と書きかえることで、ハイフンを含んだ文も、ドットを含んだ文もgrepすることができる正規表現を書くことができた。
終わりに
正規表現は記号が検索しにくいというところもあってなかなか調べるのが難しい([]
で囲う表記を文字クラスと呼ぶことも今回初めて知った)。
オライリー本を買ってちゃんと読むべきか。
参考
- 正規表現 -ハイフン 判定
- 正規表現言語 - クイック リファレンス | Microsoft Docs
.NET
用のリファレンスのようだが、初歩的なところがちょうどいい文量でまとめてあったので。
- RegExr
- オンラインで正規表現を確認できる。正規表現で検索したい例文を自分で用意することもできたので便利。