正規表現で文字列の否定

入力チェックなどでお世話になる正規表現ですが、これがなかなか奥が深い。複雑な正規表現は一体何をしているのか解析するだけでも一苦労。

この前壁にぶつかったのが 「ある特定の"文字列"を含まないようにチェックをかけたい」 というもの。ある特定の1文字を含まないような正規表現は簡単ですが、文字列となると、これが結構難しい。

たとえば「a」と「b」は含まれていていいけど、「ab」という文字列は駄目という場合。なんとなく ^[^(ab)]+$ でいけそうな気がするけど、これでは駄目。

ちなみに正規表現を試したいときはここのサイトを利用すると便利。どれがマッチしたのかを視覚的に表示してくれるので、とってもわかりやすい。

image

「ab」の文字列を否定する場合は「b」の前に「a」がないという記述をしないと駄目らしい。ここを参考に。実際の正規表現はこんな感じ。 ^(([^b]|[^a]b)|[^a]a)+$

image

ちなみに頑張って正規表現でチェックする必要はない。

<2009/05/14 追記>
コメントで教えてもらったサイトが分かりやすく解説しているので、そちらも参考に。

コメント

  1. PCREでは"先読み"というものが
    使えるのでこのように書けますよ。

    ((?!ab).)+

    文字列の否定についてはこれらの
    ページが参考になると思います。

    先読みが使える場合の文字列の否定(名前クリックで飛べます)
    http://funcchan.blog16.fc2.com/blog-entry-19.html#strdeny

    先読みが使えない場合の文字列の否定
    http://funcchan.blog16.fc2.com/blog-entry-39.html

    先読みについての解説
    http://funcchan.blog16.fc2.com/blog-entry-36.html

    PCREの話ではなかったらごめんなさい^^;

    返信削除
  2. 本当ですね。
    知りませんでした・・・。(汗
    教えて頂いたサイトも何やら分かりやすそうな感じですね。
    コメントありがとうございます。

    あー、Googleで「正規表現 文字列 否定」で検索すると上位にヒットするのが恥ずかしい・・・・

    返信削除

コメントを投稿

このブログの人気の投稿

【.NET】DataGridViewを選択した際に背景色を変更しない

Can't open PID file /var/run/nginx.pid (yet?) after start: Too many levels of symbolic links

【PostgreSQL】ROWNUMのように行番号(現在行)を取得するROW_NUMBER