2020年6月18日木曜日

正規表現の否定先読み

 いやー、、今回は(今回も)手こずった…

正規表現の否定先読み。

最初は本を読んでイマイチしっくりこなかったので色んなサイトを見比べて、実際入力してみても説明と結果が合わない。。

で、最終的に腑に落ちた自分の考え方は以下の通り。

文字列、「aaatestccc」の「test」を検索対象として、
検索対象の直前/直後にフィルタしたい文字の有無をチェックするという動作になる。



testより左にある文字列(aaa)を直前(?<)
testより右にある文字列(ccc)を直後(?)

かなり分かりづらいですが、「先読み」「後読み」の区別は、
検索対象文字列をフィルタ文字の先に書くか、後に書くかの違いになります。

(検索対象文字列をフィルタ文字より)先読み
(検索対象文字列をフィルタ文字より)後よみ

これらの文字(aaa/ccc)が
入っていて欲しい場合は「=」(肯定)
不要な場合は「!」(否定)

直前の「aaa」が入っていて欲しい場合→「(?<=aaa)」
直前の「aaa」は不要な場合→「(?
直後の「ccc」が入っていて欲しい場合→「(?=ccc)」
直後の「ccc」は不要な場合→「(?!ccc)」 




例として、タイトルの否定先読みは
検索対象:「test(?!ccc)」
対象文字列:「aaatestccc」「bbbtestcde」「atestc」
とした場合、「testの直後にcccが無い文字列」を意味します。なので、
NG:「aaatestccc」
OK:「bbbtestcde」
OK:「atestc」
となります。

Online regex tester and debugger でチェックしました。




読み取りづらいかもしれませんが、比較した図を載せておきます。







 混乱した理由としては、先読み後読みについて、検索対象文字とフィルタ対象文字の順番がごっちゃになってるサイトが多く、検索対象としても微妙な内容が多かったからです。

否定先読みなのに「(?!ccc)test」としてたり、(順番が逆)
「b(?!aiu)[aeiou]t」としてたり(aiuは除くのだから[ou]にするべきでは)

これだけ情報が錯綜するということは、後から読む人が混乱する原因に多いになりえると思うので、コメントを付けるとか、この記法はあまり使わない方がいいかと思う。。

https://rubular.com/
このチェックサイトもわかりやすかった!

0 件のコメント:

コメントを投稿