• ベストアンサー

正規表現 許可文字列 かつ 指定連続文字列の排除

わかりにくいタイトルで恐縮です。 初歩的な問題かもしれませんが、もう何日も悩み続けており、ヒントでもいただけると助かります。 たとえば、 正規表現にて 英字のみ(1文字以上) という場合は preg_match("/[a-z]+/i",$string) という風にすればいいと思います。 ここで、英字のみ(1文字以上) しかし、abc という連続文字列があれば該当させない、という場合どういう正規表現を作ればいいのでしょうか? preg_match("/[a-z^(abc)]+/i",$string) みたいなヘンテコなものを作ってみたりしてみたのですが、文法違いなのか、やはり正常には動いてくれません。 ([^a][^b][^c]) なんていうのも違いますし。 狙いは、文字列の最初でも最後でも途中でも、指定文字以外や指定連続文字列がある場合は、エラーを出す、というようなものにしたいのです。 なにかヒントいただければと思います。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

「Perl正規表現雑技」にそのまんまズバリな解答がありました。 ご質問の条件に合うようアレンジし、PHPで書くと次のようになります。 preg_match("/[0-9]+(?:(?!abc)[a-zA-Z])+[0-9]+/",$string) ちなみに、指定連続文字列が大文字小文字を区別するものと仮定して、敢えてi指定はしていません。 私の環境で試した結果、次のようになりました。 [12345ababbccc67890]:OK! [12345abcabbcc67890]:NG! [12345abbabccc67890]:NG! [12345aabbbabc67890]:NG! [12345ababb@$&67890]:NG! [12345ABBABCCC67890]:OK! ←大文字小文字を区別しているのに注意! [12345abc67890]:NG!

参考URL:
http://www.din.or.jp/~ohzaki/regex.htm#Without
SHlVA
質問者

お礼

skytemple様 回答ありがとうございます。 とてもシンプルで書きやすいですね。 本当に知らないことだらけです。 参考サイトを見ていろいろ勉強していきたいと思います。 ありがとうございました。

その他の回答 (2)

  • taskuni
  • ベストアンサー率71% (49/69)
回答No.2

preg_match("/(?(?=.*abc.*)^$|^[0-9]+[a-z]+[0-9]+$)/i",$str,$matches) 面白そうだったので作ってみましたが、あまり自信はありません。 (?=.*abc.*)が成立した場合、^$で必ず失敗、 (?=.*abc.*)が成立しなかった場合、^[0-9]+[a-z]+[0-9]+$を評価する正規表現です。(?) 合っているかどうか良く分かりません。

SHlVA
質問者

お礼

taskuni様 お礼が遅くなり申し訳ございません。 教えていただいたように試してみました。 思うような結果ができました!! 勉強になりました。 ありがとうございました。

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.1

正規表現一回でできるような気もしますが、 とりあえずif文でやればできます。 if (preg_match("/[a-z]+/i",$string) and !preg_match("/[abc]/i",$string)) { #OK } else { #NG }

SHlVA
質問者

補足

moon night様 ご回答ありがとうございます。 おっしゃるとおり、2度にわけるとできそうですね。 ただ、できれば正規表現1回でやれたらと思います。 また、運用上 18273aswjsi18726 という感じの文字列から探すことになり preg_match("/[0-9]+XXXX[0-9]+/i",$string); の XXXX の部分をどう作ればいいのか、と考えておりました。 先に言うべきことでした、申し訳ないです。