2012-06-21 5 views
7

私が取り組んでいるウェブサイトは、私がテストした他の場所でも動作すると思われるPHP(preg_match)正規表現パターンを使ってデータとマッチしません。そのパターンは:これらの正規表現のパターンは異なりますか?

<channel.*?>(.*?)</channel> 

これは、チャンネルタグを持つRSSフィードと照合されます。

に変更している場合今、私が働いているサーバーのみが正しい結果を生成します:誰もがあれば私に言うことができる場合、私は思ったんだけどだから私の正規表現は、世界で最高ではありません

<channel.*?>(.*)?</channel> 

2つのパターンの間に大きな違いがあります。

小さなメモ:SimpleXMLなどを使う方が良いかもしれませんが、この正規表現は以前のアプリケーションからのものであり、さまざまな理由から変更できません。

ありがとうございました。

+2

を使用するには、 ''あなたのPCREの区切りですか?もしそうなら、 's'修飾子は違いをもたらすかもしれません(私は完全にはわかりません)。 – BoltClock

+0

はい ''はPCRE区切り文字です。もともとコードを書いた人が誰でも使っていました。通常は '#'や '〜'を使います。 – Vunus

答えて

7

(.*)というステートメントは、「選択範囲は0文字以上です」と表示され、末尾の?はオプションです。対照的に、(.*?)は、「怠惰な星」(*?)を使用しています。最初は、完全に一致をスキップします。詳細については、thisを参照してください。

通常の(欲張りな)星と怠惰な星の違いを理解するには、PHPの次の例を見てください。貪欲な星は与えられたパターンと最も一致しますすぐにそれがマッチパターン満足しているように「あきらめる」:正規表現で

$inputs = array('axb' , 'axxxb' , 'axbxb' , 'axbxxxb'); 

// GREEDY STAR (NORMAL) 
foreach($inputs as $input) 
{ 
    preg_match('/a.*b/' , $input , $greedy); 
    $greedy_matches[] = $greedy[0]; 
} 

print "<pre>"; 
print_r($greedy_matches); 
print "</pre>"; 
/* 
Array 
(
    [0] => axb 
    [1] => axxxb 
    [2] => axbxb 
    [3] => axbxxxb 
) 
*/ 



// LAZY STAR 
foreach($inputs as $input) 
{ 
    preg_match('/a.*?b/' , $input , $lazy); 
    $lazy_matches[] = $lazy[0]; 
} 

print "<pre>"; 
print_r($lazy_matches); 
print "</pre>"; 
/* 
Array 
(
    [0] => axb 
    [1] => axxxb 
    [2] => axb 
    [3] => axb 
) 
*/ 
+0

ありがとうございます。それは膨大な手数料(回答者全員のおかげで)を助けました。私が持っている小さな質問の1つは、もともと '。(?*)'だったコードは、私自身のサーバーを含めてどこでもうまく動作しているようですが、この単一のサーバーは '(。*)?それは "怠惰な星"のためか、それはそのサーバーと正規表現のマッチングについて何か奇妙なことがありますか? – Vunus

+0

レイジースターはIIRCのPerlから来ているので、この特定のサーバーがレイジースターを実装していない正規表現ライブラリを使用している可能性があります。 –

+0

ちょうどチェック&それは私の聞いた最高の説明になるように私のバージョンにperlの別のバージョンがあります。ありがとう。 – Vunus

-1

を、* 0回以上の意味 - 追加する必要はありませんか?その後。

編集:私は今、コメントから理解し、貪欲が違いになります。少しテストケース:

var_dump(preg_replace('/<channel.*?>(.*?).*<\/channel>/', '$1', '<channel>asd</channel>')); 
var_dump(preg_replace('/<channel.*?>(.*)?.*<\/channel>/', '$1', '<channel>asd</channel>')); 

出力

string(0) "" 
string(3) "asd" 

ご覧のとおり貪欲であることは違いを作るなるように、私は、(.*?).*(.*)?.*を使用しています。しかし、それは同じではないので、与えられた例で私はそれが違いを生む方法を見ません。

+3

'*?'はungreedyゼロ以上の数量子です。 –

2

私の推測では、実際にはオペレータ自身が怠惰であることを望んでいないということです。遅延オペレータは、一般に可能な限り一致させることを試みますが、不規則なデータを扱う場合には予​​期しない結果を招く可能性があります。欲張りグループの最後に疑問符を置くことで、グループを非欲張り(怠け者)にするのではなく、欲張りグループに任意の一致を追加します。貪欲と怠惰の区別について詳しくは、http://www.regular-expressions.info/possessive.htmlをご覧ください。

0

照合しようとしているテキストの例を示してください。

'<channel.*' will match anything starting with <channel 

'?>' will match a single character followed by > (so '1>', '2>', 'b>' etc) 

あなたは 間のすべてを一致させたい場合は、単にパターン

'#<channel>(.*)</channel>#' 
関連する問題