2009-08-13 21 views
3

%で囲まれた部分文字列にマッチさせようとしていますが、preg_match_allは同じ行に同時に複数の文字を含むようです。%の間の文字列を一致させる正規表現%

コードは次のようになります。次の出力を生成し

preg_match_all("/%.*%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches); 
print_r($matches); 

を。

Array 
(
    [0] => Array 
     (
      [0] => %hey%_thereyou're_a%rockstar% 
      [1] => %there% 
     ) 

) 

しかし、私はそれではなく、次の配列を生成したいと思います:

[0] => %hey% 
[1] => %rockstar% 
[2] => %there% 

私は何をしないのですか?

答えて

12

[^%] 『を使用して、正規表現で「.」を置き換えます。何が起こっている

preg_match_all("/%[^%]*%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches); 

は』 .は」すべてのものを含め、それはおそらくできる限りのマッチング「貪欲」であるということですアップ行の最後の%に移動します。無効化された文字クラス "[^%]"に置き換えると、パーセントを除く)のいずれかと一致し、目的のビットに一致するようになります。

別のオプションは、それは「貪欲はいけない」よう指示ドット、後に「?」を配置するために、次のようになります。いずれか、上記の例で

preg_match_all("/%.*?%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches); 

オプションが動作します、しかし、時間がありますあなたが単一の文字よりも大きなものを探しているかもしれないので、否定された文字クラスは助けにならないので、解決策はマッチを解き放つことです。

/%.*?%/ 

改行がマッチ内部で発生することができた場合は、S(DOTALL)修飾子を追加します:

/%.*?%/s 
+0

これは機能します。ありがとう! – Spoike

4

やっていますその理由は、スターが貪欲であるからです。つまり、スターは、正規表現エンジンに先行するトークンを可能な限り頻繁に繰り返させます。試してみてください 。*?代わりに。

1

それはungreedyにするために?を使用する - あなたは貪欲な試合を

1

あなたは/%[^%]+%/を試すことができます。これは、パーセント記号の間に、パーセント記号ではない文字と一致させたいことを意味します。

パターンを不自然にすることもできます。 /%.+%/Uなので、できるだけキャプチャされません(私は思っています)。

+0

もっと正確に言えば、 '/ U'は正規表現中のすべての量子の貪欲さを反転させるので、' /%.+%/U'は '/%.+?%/'と '/%.+%%/U'は '/%.+%/ 'と同じです。 http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php –

2

? *:

preg_match_all("/%.*?%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches); 
1

|%(\ w +)%|これはまさにあなたが望むものを動作させます。

関連する問題