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%

私は何が欠けていますか?

4

7 に答える 7

12

.正規表現の " " を " " に置き換えます[^%]

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

何が起こっているかというと、 " ." は、行の最後の % までのすべてを含めて、可能な限り「貪欲に」一致しているということです。これを否定された文字クラス " " に置き換えると、[^%]代わりにパーセント以外のすべてに一致することを意味します。これにより、必要なビットだけに一致するようになります。

別のオプションは?、ドットの後に " " を配置することです。これは、「貪欲にならない」ことを示します。

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

上記の例では、どちらのオプションも機能しますが、1 文字よりも大きなものを検索する場合があるため、否定された文字クラスは役に立たないため、解決策は一致の貪欲化を解除することです。

于 2009-08-13T08:06:28.660 に答える
4

貪欲なマッチを行っています - 貪欲で?ないものにするために使用します:

/%.*?%/

マッチ内で改行が発生する可能性がある場合は、s (DOTALL) 修飾子を追加します。

/%.*?%/s
于 2009-08-13T08:07:26.273 に答える
2

?を追加します 後に *:

preg_match_all("/%.*?%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches);
于 2009-08-13T08:09:53.960 に答える
1

|%(\w+)%| これは、あなたが望むものとまったく同じように機能します。

于 2009-08-19T10:51:04.887 に答える
1

その理由は星が貪欲だからです。つまり、スターによって、正規表現エンジンは前のトークンをできるだけ頻繁に繰り返すようになります。試してみてください 。*?代わりは。

于 2009-08-13T08:07:51.640 に答える
1

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

また、パターンを貪欲でないものにすることもでき/%.+%/Uます。

于 2009-08-13T08:07:53.043 に答える