Php 正则表达式匹配%

Php 正则表达式匹配%,php,regex,preg-match-all,Php,Regex,Preg Match All,我试图匹配包含在%中的子字符串,但是preg\u match\u all似乎在同一行中同时包含多个 代码如下所示: preg_match_all("/%.*%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches); print_r($matches); 它将生成以下输出 Array ( [0] => Array ( [0] => %hey%_thereyou're_a%roc

我试图匹配包含在%中的子字符串,但是
preg\u match\u 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%
我缺少什么?

将正则表达式中的“
”替换为“
[^%]
”:

所发生的事情是“
”正在“贪婪地”匹配尽可能多的匹配,包括行中最后%的所有内容。将其替换为否定字符类“
[^%]
”意味着它将匹配除百分比之外的任何内容,这将使它只匹配您想要的位

另一种选择是在点后放置一个“
”,告诉它“不要贪婪”:


在上面的示例中,这两个选项都可以使用,但有时您可能会搜索大于单个字符的内容,因此求反字符类不会有帮助,因此解决方案是取消匹配的贪婪性。

您正在进行贪婪匹配-使用
将其取消冻结:

/%.*?%/
如果匹配中可能出现换行符,请添加s(点全部)修改器:

/%.*?%/s

原因是那颗星很贪婪。也就是说,星号使正则表达式引擎尽可能频繁地重复前面的标记。你应该试试看?相反。

您可以尝试
/%[^%]+%/
-这意味着在百分比符号之间,您只希望匹配不是百分比符号的字符

您也可以将模式取消冻结,例如,
/%.+%/U
,这样它将捕获尽可能少的内容(我认为)。

添加一个?在*之后:

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

|%(\w+)%|这将完全满足您的要求。

更准确地说,
/U
反转正则表达式中所有量词的贪婪程度,因此
/%.+%/U
/%.+?%/
相同,
/%.+?%/U
/%.+////.code>相同。
/%.*?%/s
preg_match_all("/%.*?%/", "%hey%_thereyou're_a%rockstar%\nyo%there%", $matches);