2012-03-14 8 views
4
php > preg_match("@/m(/[^/]+)+/t/[email protected]", "/m/part/other-part/t", $m); 
php > var_dump($m); 
array(2) { 
    [0]=> 
    string(20) "/m/part/other-part/t" 
    [1]=> 
    string(11) "/other-part" 
} 
php > preg_match_all("@/m(/[^/]+)+/t/[email protected]", "/m/part/other-part/t", $m); 
php > var_dump($m); 
array(2) { 
    [0]=> 
    array(1) { 
    [0]=> 
    string(20) "/m/part/other-part/t" 
    } 
    [1]=> 
    array(1) { 
    [0]=> 
    string(11) "/other-part" 
    } 
} 

をキャプチャを定量化して、私は残念ながら、私は期待して、両方を捕捉しない/m(/[^/]+)+/t/?正規表現で、/part/other-partの両方に一致するようにキャプチャをしたいと思い例と述べました。正規表現は

このキャプチャは、このサンプルと一致するようにバインドすべきではありません。キャプチャグループの定義されていない回数だけキャプチャする必要があります。例えば/m/part/other-part/and-another/more/t

UPDATE: これは私の質問は、私は私のこのマッチングを達成することができるだろうかのよう立つ予想される動作であることを考えると?

+1

私はキャプチャグループが原因数量詞 '+' – mhitza

+0

に繰り返し適用することが期待される。また、 "動作しませんが、" 良いではありません質問のタイトルを持つこと。そして、実際には、数値限定子はPCREで発表されたように機能します。 – hakre

+0

@hakreタイトルから機能しない部分を削除しました。あなたの答えに基づいて、キャプチャグループの定量化を思い出したので、私の記憶が私を欺いているようです。 – mhitza

答えて

2

すると、このいずれかを試してみてください:

preg_match_all("@(?:/m)?/([^/]+)(?:/t)[email protected]", "/m/part/other-part/another-part/t", $m); 
var_dump($m); 

それが与える:

array(2) { 
    [0]=> 
    array(3) { 
    [0]=> 
    string(7) "/m/part" 
    [1]=> 
    string(11) "/other-part" 
    [2]=> 
    string(15) "/another-part/t" 
    } 
    [1]=> 
    array(3) { 
    [0]=> 
    string(4) "part" 
    [1]=> 
    string(10) "other-part" 
    [2]=> 
    string(12) "another-part" 
    } 
} 

// EDIT

IMOあなたが欲しいものを行うための最善の方法は、(するpreg_matchを使用することです)@stemaからして、必要な部品のリストを取得するために/によって結果爆発します。すでにコメントで書かれ

+0

'/ m'はオプションです。なぜあなたがそれをするのか理解していますが、それは間違っていませんか? – hakre

+0

ええ、それは不正確ですが、正規表現よりもオプションではない場合、彼が望む部分を爆発させることはできません。私は単純な 'preg_match()' + 'explode()'を使って彼が望む部分を得るでしょう。 – piotrekkr

+0

@piotrekkrあなたの回答は質問に一層合っています(私はそれを受け入れます)。しかし、私はpreg_match()を実行し、文字列が(/ m)で始まり、(/ t /?)で終わるならば、厳密な事前チェックをする代わりに、preg_match()を実行し、 – mhitza

2

これは、キャプチャグループの動作方法です。繰り返しのキャプチャグループには、正規表現の終了後に最後に一致したものだけが格納されます。それはあなたのテスト "/ other-part"にあります。

/m((?:/[^/]+)+)/t/? 

代わりにこれを試してみては試合の上にホバリングしながら、あなたはキャプチャグループの内容を見ることができ、それhere on Regexr参照してください。

最初に?:を追加してグループをキャプチャしないようにして、繰り返し全体に別のグループを追加してください。 PHPで

preg_match_all("@/m((?:/[^/]+)+)/t/[email protected]", "/m/part/other-part/t", $m); 
var_dump($m); 

出力:

array(2) { 
    [0]=> array(1) { 
     [0]=> 
     string(20) "/m/part/other-part/t" 
    } 
    [1]=> array(1) { 
     [0]=> 
     string(16) "/part/other-part" 
    } 
} 
+0

最新の質問をご覧ください。それがそうであれば、私はまだこれがどのように達成されるのか知りたいと思うでしょう。 – mhitza

+0

@mhitzaはすでに私の答えを更新しました。 – stema

0

としてはpreg_matchはあなたが同じサブグループが同様にマッチし返すことはできませんので、あなたは(あなたはJavascriptや.NETを使用して実行できるように、Get repeated matches with preg_match_all()参照)一度にこれを行うことはできません。だから、複数のステップに操作を分割することができます

  1. が被写体と一致、あなたが興味のある部分を抽出
  2. マッチ興味部分だけを。

コード:

$subject = '/m/part/other-part/t'; 
$subpattern = '/[^/]+'; 
$pattern = sprintf('~/m(?<path>(?:%s)+)/t/?~', $subpattern); 
$r = preg_match($pattern, $subject, $matches); 
if (!$r) return; 
$r = preg_match_all("~$subpattern~", $matches['path'], $matches); 
var_dump($matches); 

出力:

array(1) { 
    [0]=> 
    array(2) { 
    [0]=> 
    string(5) "/part" 
    [1]=> 
    string(11) "/other-part" 
    } 
}