Perlのパターンマッチングについて

[上に] [前に] [次に]
匿名希望 1998/06/03(水) 13:36:05
アホみたいな質問で、しかも具体的すぎて申し訳ないんですが、
少々教えていただきたい事があります。

Perlのパターンマッチングなんですが、例えば・・・・。
$str = "abcdefabcdef"
という文字列があったとします。この時に・・・・。
「この中から「b」で始まり「e」で終わる文字列を抜き出して、その文字列を置換したい」
というような場合、いったいどうすれば良いのでしょうか?

「$str =~ s/〜」を使うような気はしてるんですが、
「ただ「b」で始まり「e」で終わる文字列」と言っても、
この場合だと置換対象になる文字列は、
「bcde」と「bcdefabcde」の2通りが考えられると思うんです。
そのへんの区別の方法なんかがわかれば嬉しいんですが・・・・。

誰か教えていただけないでしょうか。

mo [E-Mail] 1998/06/03(水) 14:49:18
このサンプルを参考にしてみてください。

$str = "abcdefabcdefabcdef";
$x = $y = $z = $str;

# 最長マッチ
$x =~ s/b.*e/XXX/;

# 最短マッチ
$y =~ s/b[^e]*e/XXX/;

# 2 個分にマッチ。
$z =~ s/b([^e]*e){2}/XXX/;

print "x=$x\n";
print "y=$y\n";
print "z=$z\n";

mo [E-Mail] 1998/06/03(水) 15:10:30
捕捉です。
一般的な正規表現で使われる '*' は最長マッチですが、perl5 で拡張された
'*?' を用いることで最短マッチが利用できます。
上記例で、

# 最短マッチ
$y =~ s/b.*?e/XXX/;

としても同じことです。
この最短マッチがあることで、正規表現がかなり強力になります。
HTML のコメントにマッチする正規表現
("<!--" で始まって、最初に "-->" があらわれるところまで)
にマッチするパターンを考えると実感すると思いますが、
最短マッチを用いないで記述するのは至難の技です。

B-Cus 1998/06/04(木) 00:33:14
さらに補足。

regexpがマッチするときの基本原則は
 1. 最も左にあるもの
 2. 最長なもの
です。1は2に優先します。

 "ABABB" =~ m/A.*B/;
→  "ABABB"にマッチ (ABでもABBではない。最長でないから)
 "ABABB" =~ m/AB+/;
→  最初の"AB"にマッチ (ABBの中の"AB"ではない。最左でないから)

というわけでございます。

mm 1998/06/04(木) 02:16:50
ついでに哺足。

最左最長が原則でいいのですが、
たとえば、| が入ると、ちょっとややこしくなります。
(昔、これでしくじったことがあります(^^;)

"ABABB" =~ m/AB|A.*B/;
→  最初の"AB"にマッチ(最長ではなく、| の左が優先)
"ABABB" =~ m/BA|A.*B/;
→  "ABABB"にマッチ(最左が優先)

匿名希望 1998/06/04(木) 13:36:45
[[解決]]
回答だけでなく、いろいろな補足までしていただいてありがとうございました。
ヘタな参考書より断然わかりやすかったです。
おかげで自分のやりたい事が何とかできました。

これからも精進していきます。みなさんありがとうございました。

[上に] [前に] [次に]