2011-10-24 8 views
1

私は文字列内の2つの部分をPHPの正規表現と照合しようとします。貪欲に問題があると私は思う。私は、最初の正規表現(コメントを参照してください)私に最初の2つの正規表現として、2つのキャプチャを与えるが、まだ両方の文字列をキャプチャします。私は間違って何をしていますか?正規表現が一致しません、greediness

+123(最初の文字列のようにcd:が存在する場合)と456を取得しようとしています。

<?php 

$data[] = 'longstring start waste cd:+123yz456z longstring'; 
$data[] = 'longstring start waste +yz456z longstring'; 
$regexs[] = '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/'; // first 
$regexs[] = '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/'; // second 

foreach ($regexs as $regex) { 
    foreach ($data as $string) { 
    if (preg_match($regex, $string, $match)) { 
     echo "Tried '$regex' on '$string' and got " . implode(',', array_split($match, 1)); 
     echo "\n"; 
    } 
    } 
} 
?> 

出力は次のとおりです。

Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste +yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 

cd:は、2番目の文字列中に存在していないので、何の四行目はありません。

の予想される出力の最初の行は、実際の出力とは異なり、(私は専門家だからです):

Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 
Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste +yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 
+0

が見えます。 – Chriszuma

+2

また、キャプチャしようとしていることを言葉で説明できますか?それはあまり明らかではありません。 – Chriszuma

+0

@Chriszuma 'cd:'がその文字列に存在しないので、2番目の正規表現は2番目の文字列と一致しません。 – bloodphp

答えて

1

大丈夫、あなたはcd:がある場合+123をキャプチャしたい、と常に456?ここで私はそれを行うだろう方法は次のとおりです。非貪欲(?)乗算器のリベラル使用あなたはそれが正確に何をしたい行うために取得することができますして

$data[] = 'longstring start waste cd:+123yz456z longstring'; 
$data[] = 'longstring start waste +yz456z longstring'; 

$regexs[] = '/start.+?(?:cd:(.+?)y)?.*?z(.+?)z/'; 

(?:)ノンキャプチャグループにも注意してください。彼らは非常に便利です。

EDITは、どうやらそれは、仕事のは、「どちらか/または」グループと、別のアプローチを試みることはできません:あなたは、出力の行を忘れてしまったよう

$regexs[] = '/start.+?(?:cd:(.+?)yz(.+?)z|\+yz(.+?)z)/'; 
+0

お返事ありがとうございます。 regex: 'Tried '/start.+?(?cd:()+?)y)?.*???((++))/' on 'longstring start waste CD:+ 123yz456z longstring'およびgot、456' 何らかの未知の理由で '+ 123'を捕まえなかったようです。 – bloodphp

+0

'(?:)'に関するヒントをありがとう。それはクールだった! (それが可能であるかどうかはわかりませんでした) – bloodphp

+0

これはうまくいかなかったのですが、私は答えを編集して別の方法を試みました。 – Chriszuma

関連する問題