• ベストアンサー

正規表現の(?=と(?!の使い方

タイトルの通りです。 (?=と(?!の使い方がいまいち理解できません。 具体的な使用例とともに教えてもらえませんか?

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

  • ベストアンサー
  • kabaokaba
  • ベストアンサー率51% (724/1416)
回答No.3

Perl/Python/.NET/Java(Sunのライブラリ)/Rubyあたりで つかえる正規表現ですな. 他にも使える言語はあるかも. (?= ... )は先読み,(?! ... )は先読みの否定ってあたりまでは 質問者も知ってるのでしょうね とりあえずPerlだとしましょう. m/foo(?=bar)/ これは fooのあとにbarがあるものにマッチ.だから foobarはOK,fooBARはだめ. foofoobarはOK m/foobar/とm/foo(?=bar)/の違いは実際にマッチして 正規表現エンジンが見ている場所がどう動くか. m/foobar/の場合はbarの直後を見てるけども m/foo(?=bar)/の場合はfooの直後をみてる 以下のコードの結果を参照. $A="foobar"; $A=~m/(foobar)/; print $1,"\n";### foobar $B="foobar"; $B=~m/(foo(?=bar))/; print $1;##fooだけ オライリーの「詳説正規表現」pp.64--65には s{(\d) (?= (\d\d\d)+ (?!\d) )} {$1,}gmx; と等価な例がでています. これは数字の三桁ごとにカンマ(,)を挿入します. つまり,例えば1234567m => 1,234,567m という動きをします. 1を(\d)でキャプチャして, 次に 「三桁の数字(\d\d\d)の塊が一個以上」と その先に「数字がない」 ということを先読みします. 今回は 1がマッチ, (\d\d\d)+ が 234567 とマッチ mが(?!\d)とマッチします. したがって,マッチ成功で $1 には 1 が入ります. したがって,最初は 1,234567m となりますが,gで修飾されてるのでまだ進みます. このとき,(?= )があるので,正規表現エンジンは カンマ(,)と2の間を見ています.つまり,次は 234567mに対して同様の処理が進みます. 今度は 2 345 67 と行くのですが,マッチ失敗です.(\d\d\d)+ があいません. そこで次は 34567mを相手にします. 3 456 7と進んでマッチ失敗です.(\d\d\d)+ があいません. 次は 4567mを相手にして 4 567 m で今度は成功したがって 放置された 23 もあるので 1,234,567m となります.正規表現エンジンは4の後のカンマと5の前を見ています. 次は 567mを相手にしますが,もうこれはマッチしません. #実際は正規表現エンジンはこれに対しても作業をすると思うのですが #明らかなので省きます. このあたりの正規表現は実装ごとに微妙に違うので要注意です. (?= ),(?! )あたりならまだしも (?<= ),(?<! )あたりだといろいろあるようです.

その他の回答 (3)

  • da-te
  • ベストアンサー率37% (3/8)
回答No.4

こんにちは。 情報ありがとうございます。 URL先の内容を確認してみました。 この例文ですと、「|」を使ってないのでわかりにくいかもしれませんね。 例えば、 AB ABA ABB ABC ABD という文字列があるとして、 AB(?= C|D ) とすると、マッチするのは、 AB、ABC、ABD となります。 また、 AB(!= C|D ) とすると、マッチするのは、 AB、ABA、ABB となります。 こんな感じでいかがでしょうか。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

Perl5の(今ではPerl以外でも大概のところで使えますが) positive/negative look-ahead、先読み機能ってことですか? まあ変態的な使いかたもありますがわかりやすいところでこんなのではどうでしょう? #!/usr/bin/perl use strict; use warnings; while (<DATA>) { chomp; print "$_ → "; print $& if /[0-9.]+(?=円|ドル)/; print "\n"; } __END__ 25ドル 42.195km 99800円 995hPa 100m走 実行結果: 25ドル → 25 42.195km → 99800円 → 99800 995hPa → 100m走 → この例では、数値の部分だけ取り出したいけど、その数値は 金額を表しているものだけ取り出したい。という感じですね。 先読みなしだと単位のところまでマッチさせておいてあとで削るとか ()をつかって数値の部分だけをグループ化しておいてそのグループを取り出す といったことをしなければなりません。

  • da-te
  • ベストアンサー率37% (3/8)
回答No.1

こんにちは。 正規表現のメタ文字は「?」だけという認識でお答えします。 (「(」と「=」、「!」は文字列という認識) 「?」は、0個か1個の文字に代用して表現する。という意味です。 ですので、 (?= なら、 (=、(0=、(9=、(a=、(Z=、(あ=、などになりますし、 (?! なら、 (!、(0!、(9!、(a!、(Z!、(あ!、などになります。 こんな感じでいかがでしょうか。 尚、使用する言語の情報があれば、もっと詳しい説明が得られると思います。

noname#108740
質問者

補足

すいません。 http://www.kt.rim.or.jp/~kbk/regex/regex.html#POSITIVELOOKAHEAD ↑これなんですけど、どういうときに使うのかがよくわからないんです。

関連するQ&A

専門家に質問してみよう