8

私が取り組んでいるWebサイトは、PHP(preg_match)正規表現パターンを使用してデータと一致しません。これは、私がテストした他のすべての場所で機能するようです。そのパターンは次のとおりです。

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

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

これで、作業中のサーバーは、次のように変更した場合にのみ正しい結果を生成します。

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

私の正規表現は世界で最高ではないので、2つのパターンの間に有意差があるかどうか誰かに教えてもらえないかと思います。

小さなメモ:SimpleXMLなどを使用する方がおそらく良いと思いますが、この正規表現は以前のアプリケーションのものであり、さまざまな理由で変更することはできません。

洞察を事前に感謝します。

4

4 に答える 4

7

ステートメント(.*)は「選択は0文字以上です」と述べており、末尾?はオプションの一致になります。対照的に、最初に試合を完全にスキップしようとする(.*?)「レイジースター」()を使用しています。詳細については、これ*?を確認してください。

通常の(貪欲な)星と怠惰な星の違いを理解するには、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
)
*/
于 2012-06-21T14:00:02.077 に答える
2

私の推測では、実際には演算子自体を怠惰にしたくないと思います。怠惰な演算子は通常、可能な限り一致させようとしません。これは、不規則である可能性のある大量のデータを処理するときに予期しない結果をもたらす可能性があります。欲張りグループの最後に疑問符を配置することで、グループを欲張りでない(怠惰な)ものにするのではなく、欲張りグループにオプションの一致を追加します。貪欲と怠惰の違いについてもっと知りたい場合は、http://www.regular-expressions.info/possessive.htmlをチェックしてください。

于 2012-06-21T14:01:42.357 に答える
0

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

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

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

パターンを使用するだけですべてを一致させたい場合

'#<channel>(.*)</channel>#'
于 2012-06-21T14:10:03.777 に答える
-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"

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

于 2012-06-21T14:00:19.930 に答える