1

文字列内の 2 つの部分を PHP の正規表現と一致させようとしています。貪欲さに問題があると思います。最初の正規表現 (コメントを参照) で最初の 2 つのキャプチャを 2 番目の正規表現として取得したいのですが、それでも両方の文字列をキャプチャします。私は何を間違っていますか?

+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

は 2 番目の文字列に存在しないため、4 行目cd:はありません。

予想される出力 (私は専門家ではないため)。最初の行は実際の出力とは異なります。

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
4

1 に答える 1

1

さて、あなたは、、そして常に+123あるかどうかをキャプチャしたいですか?これが私がそれをする方法です:cd:456

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

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

欲張りでない(?)乗数を自由に使用することで、希望どおりの動作を実現できます。

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

編集どうやらそれはうまくいきません、「どちらか/または」グループで別のアプローチを試してみましょう:

$regexs[] = '/start.+?(?:cd:(.+?)yz(.+?)z|\+yz(.+?)z)/';
于 2011-10-24T19:52:39.627 に答える