それなに
正規表現の話です。
検索ワードの前後にも条件をつけるときに使う。
なんとなく解らないのでなんとなく敬遠するもののひとつ。
- 肯定先読み
- 否定先読み
- 肯定後読み
- 否定後読み
日本語訳した人には申し訳ないが、直感的じゃないので忘れることにする。
書き方 | 意味 |
---|---|
(?=regex) | 直後にregexがある |
(?!regex) | 直後にregexが無い |
(?<=regex) | 直前にregexがある |
(?<!regex) | 直前にregexが無い |
要するに、基本系が(?=regex)
で、否定なら!
にして、直前なら<
を追加する。
例)
(?<=hoge)foo(?!bar) → 直前に_hoge_があり、直後に_bar_が無いfoo
にマッチ
(?<!hoge)foo(?=bar) → 直前に_hoge_が無くて、直後に_bar_があるfoo
にマッチ
構文の中に丸括弧とかいろいろあるけど、マッチする箇所がfoo
だけなのが重要なところです。
いつ使うのよ
大量の名前リストから「しむらけん」を「バカ殿様」に置換することが年に2回くらいあると思いますが、
cat regex.ja
にしむらけんたろう
にしむらけん
しむらけんたろう
しむらけん
ふつうにやると「にしむらけんたろう」とか「にしむらけん」とか「しむらけんたろう」にもマッチしてしまいます。
cat regex.ja | perl -pe 's/しむらけん/バカ殿様/'
にバカ殿様たろう
にバカ殿様
バカ殿様たろう
バカ殿様
だめだこりゃ。「しむらけん」のみを「バカ殿様」に修正するには
cat regex.ja | perl -pe 's/(?<!に)しむらけん(?!たろう)/バカ殿様/'
にしむらけんたろう
にしむらけん
しむらけんたろう
バカ殿様
だっふんだ。
おまけ:GNU と BSD
Mac の人はそのままだと grep で Perl 風正規表現が使えないかもしれないので、GNU版 grep 入れるといいよ。
-P, --perl-regexp PATTERN is a Perl regular expression
brewがあれば、これで。
brew install homebrew/dupes/grep
alias grep='ggrep --color'
cat regex.ja | grep -P '(?<!に)しむらけん(?!たろう)'
しむらけん
参考にしたサイト
https://regex101.com/
https://www.regexpal.com/
https://www.rexegg.com/regex-lookarounds.html
あいーん。