否定の先読み

広告

先読みには否定の先読みも用意されています。否定先読みを行うには、パターンを「(?!」から「)」の間に記述します。

/パターン(?!否定先読みパターン)パターン/

先読みはマッチしているかどうかを調べる位置を動かさずに先読みの中のパターンがマッチするかどうかを調べるものでしたが、否定先読みは位置を動かさずに指定したパターンを否定したものにマッチするかどうかを調べます。

/(a)(?!bbb)(b)/

例えば上記の場合、「a」で始まり、「a」の後に「bbb」が記述されていないかどうかを、マッチしていれば改めて「a」の後に「b」が続く文字列にマッチします。結果的に「a」の後に「b」が続くが「abbb」とはなっていない文字列にマッチします。

× abbb
× abbbon
○ abbe
○ ab

先読みと同じく否定先読みでもマッチするかどうかは確認しますがマッチした文字列を取得しません。

例えば次の例で考えてみます。

/(?!0000)¥d¥d¥d¥d/

上記の場合、まず「0000」ではないかどうかを確認します。「0000」では無い場合に改めて対象の文字列の先頭から数字が4文字続くかどうかを確認します。結果的に4桁の数字だけど「0000」では無いものにマッチすることになります。

このように否定先読みを使うと除外したいものを指定することが可能になります。先読みも否定先読みもマッチするかどうかを調べる位置が動きませんので、複数指定することも出来ます。

/(?!0000)(?!9999)¥d¥d¥d¥d/

上記では「0000」及び「9999」ではない4桁の数字にマッチします。

サンプルプログラム

では簡単なプログラムで確認して見ます。

test2-1.rb

#! ruby -Ku
require "kconv"

def check1(str)
  if /(?!0000)¥d¥d¥d¥d/ =~ str then
    print(Kconv.tosjis("○") + str + "(" + $& + ")¥n")
  else
    print(Kconv.tosjis("×") + str + "¥n")
  end
end

def check2(str)
  if /(?!0000)(?!9999)¥d¥d¥d¥d/ =~ str then
    print(Kconv.tosjis("○") + str + "(" + $& + ")¥n")
  else
    print(Kconv.tosjis("×") + str + "¥n")
  end
end

print(Kconv.tosjis("/(?!0000)¥¥d¥¥d¥¥d¥¥d/ にマッチするかどうか¥n"))
check1("1234")
check1("9999")
check1("0000")
check1("802")

print("¥n")
print(Kconv.tosjis("/(?!0000)(?!9999)¥¥d¥¥d¥¥d¥¥d/ にマッチするかどうか¥n"))
check2("1234")
check2("9999")
check2("0000")
check2("802")

上記のプログラムを「test2-1.rb」として保存します。文字コードはUTF-8です。そして下記のように実行して下さい。

否定の先読み

( Written by Tatsuo Ikura )