3. 否定先読みで条件チェック
次は、否定先読みで条件チェックする正規表現についてです。
同じアルファベットの文字列が連続してない行を検索する。 例1 文字列aabcdeは、アルファベットの文字列aが連続しているので不適 例2 文字列abcdcdは、アルファベットの文字列cdが連続しているので不適 例3 文字列abcabcは、アルファベットの文字列abcが連続しているので不適
対象データと期待する検索結果は、下記となります(黄緑色が検索にヒットした部分です)。
こういった、同じ文字列の連続を調べる際には、後方参照を使うのがセオリーです。そして、候補となる文字列の組み合わせを全てチェックすることで、答えは下記となります。
^(?!.*([a-z]+)\1).*$
解説すると、まず行頭で否定先読みを使い.*([a-z]+)\1
を満たさないことを条件としています。.*
にマッチする文字の数は、0文字以上の文字列ですが、これはバックトラックが発生する量指定子になっています。[a-z]+
にマッチする文字の数は、1文字以上の[a-z]
ですが、これもバックトラックが発生する量指定子になっています。
以上により、たとえば検索対象がabcdefで、検索パターンが^(?!.*([a-z]+)\1).*$
だとすると、
.*が0文字にマッチ、[a-z]+が1文字にマッチ、キャプチャした\1にマッチ .*が0文字にマッチ、[a-z]+が2文字にマッチ、キャプチャした\1にマッチ .*が0文字にマッチ、[a-z]+が3文字にマッチ、キャプチャした\1にマッチ .*が0文字にマッチ、[a-z]+が4文字にマッチ、キャプチャした\1にマッチ .*が0文字にマッチ、[a-z]+が5文字にマッチ、キャプチャした\1にマッチ .*が0文字にマッチ、[a-z]+が6文字にマッチ、キャプチャした\1にマッチ .*が1文字にマッチ、[a-z]+が1文字にマッチ、キャプチャした\1にマッチ .*が1文字にマッチ、[a-z]+が2文字にマッチ、キャプチャした\1にマッチ 以下略
という全ての組み合わせで、同じ文字列が連続するかチェックされます。そして、全ての組み合わせでアンマッチだったら(?!.*([a-z]+)\1)
を満たしますので.*$
で行全体を検索しています。
正規表現のイメージは下記となります。