2016-04-04 7 views
-1

との奇妙な問題コード:PHPの正規表現 - 複数のグループのキャプチャ

$pattern = '~(/(?P<lang>en|ru))?/foo(/(?P<bar>bar))?~'; 

preg_match($pattern, '/foo', $matches); 
var_dump($matches); 
/*output: 
array(1) { 
    [0] => 
    string(4) "/foo" 
}*/ 
preg_match($pattern, '/foo/bar', $matches); 
var_dump($matches); 
/*output: 
array(7) { 
    [0] => 
    string(8) "/foo/bar" 
    [1] => 
    string(0) "" 
    'lang' => 
    string(0) "" 
    [2] => 
    string(0) "" 
    [3] => 
    string(4) "/bar" 
    'bar' => 
    string(3) "bar" 
    [4] => 
    string(3) "bar" 
}*/ 

質問:なぜ地獄、それは第二するpreg_matchコールで<lang>をキャプチャしないし、私はそれをどのように修正するのですか?

P.S.私はこの正規表現をhttps://www.regex101.comにしようとしましたが、正しくキャプチャしていますが、PHP7を使用しているマシンではそうはなりません。私は、regex101が出力をフィルタリングしていると感じます。

+0

怠け者のマッチングは、おそらく遅延マッチングに役立ちます。 '(/(?P en | ru))??/foo(/(?P bar))? ' –

+0

'lang'は一致するものがないときです。それは意味をなさない。そして、いいえ、別の '? 'を加えても助けにならなかった。 – jurchiks

+0

明確にしてください。あなたのコードデモで、 'lang'が空であることがわかります。' 'lang '=> string(0)" "'テキストはキャプチャされていません。 –

答えて

1

他の人が言っているように、それは単に正規表現の仕組みです。私が知る限り、正規表現はかなり普遍的です。それは、JavaがどのようにStringを返して関数がエラーをスローしない限りStringを返す必要があるかといった一般的なプログラミングにおいても同様です。

PHPでは、$matchesarray_filterを使用して空のエントリを削除してください。

(?:/(?P<lang>en|ru))?/foo(?:/(?P<bar>bar))?

または2つの正規表現に分割:(?:/(?P<lang>en|ru))/foo(?:/(?P<bar>bar))

はまた、私は混乱をカットする非キャプチャグループ(?:)を使用することをお勧め。