Php 正则表达式以获取匹配中的重复匹配
我在源代码中有以下示例字符串:Php 正则表达式以获取匹配中的重复匹配,php,regex,preg-match-all,Php,Regex,Preg Match All,我在源代码中有以下示例字符串: @包含插件:PluginName param1=value1 param2=value2@ 我想要的是从源代码中查找所有发生的@include_plugin:@以及PluginName和每个paramN=valueN的结果 此时此刻,我正在摆弄类似的东西(并尝试了许多变体):/@include_插件:(.*\b){1}(.*\=.}{0,}@/(使用这个)。不幸的是,我似乎无法定义一个模式,它给了我想要的结果。有什么建议吗 更新示例: 假设我在一个.tpl文件中有
@包含插件:PluginName param1=value1 param2=value2@
我想要的是从源代码中查找所有发生的@include_plugin:@
以及PluginName
和每个paramN=valueN
的结果
此时此刻,我正在摆弄类似的东西(并尝试了许多变体):/@include_插件:(.*\b){1}(.*\=.}{0,}@/
(使用这个)。不幸的是,我似乎无法定义一个模式,它给了我想要的结果。有什么建议吗
更新示例:
假设我在一个.tpl文件中有这个字符串<代码>@include_plugin:BestSellers limit=5 from category=123@
我希望它返回一个包含以下内容的数组:
0 => BestSellers,
1 => limit=5 fromCategory=123
或者更好(如果可能):
您可以使用此正则表达式:
/@include_plugin:([a-zA-Z0-9]+)(.*?)@/
PluginName在第一个捕获组中,参数在第二个捕获组中。请注意,参数(如果有)的前导空格
除非已知最大参数数,否则不可能编写正则表达式来提取更好的情况
您可以通过首先修剪前导空格和尾随空格,然后沿
/\s+/
进行额外处理。此正则表达式将为您提供多个组,每个插件一个组
((?<=@include_plugin:)(.+))
((?您可以分两步完成。首先使用正则表达式捕获行,然后将参数分解为数组:
$subject = '@include_plugin:PluginName param1=value1 param2=value2@';
$pattern = '/@include_plugin:([a-z]+)( .*)?@/i';
preg_match($pattern, $subject, $matches);
$pluginName = $matches[1];
$pluginParams = isset($matches[2])?explode(' ', trim($matches[2])):array();
这就是你要找的吗
array(3) {
[0]=>
array(2) {
[0]=>
string(55) "@include_plugin:PluginName1 param1=value1 param2=value2"
[1]=>
string(27) "@include_plugin:PluginName2"
}
[1]=>
array(2) {
[0]=>
string(11) "PluginName1"
[1]=>
string(11) "PluginName2"
}
[2]=>
array(2) {
[0]=>
string(27) "param1=value1 param2=value2"
[1]=>
string(0) ""
}
}
我不确定您的PluginName
可以包含哪些字符集或参数/值,但如果这些参数/值受到限制,您可以使用以下正则表达式:
/@include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)@/
这将捕获插件名称,后跟字母数字参数及其值的任何列表。可以通过以下方式查看输出:
<?
$str = '@include_plugin:PluginName param1=value1 param2=value2@
@include_plugin:BestSellers limit=5 fromCategory=123@';
$regex = '/@include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)@/';
$matches = array();
preg_match_all($regex, $str, $matches);
print_r($matches);
?>
要获得所需格式的数组,可以使用以下命令迭代结果:
$plugins = array();
foreach ($matches[1] as $match) {
$plugins[] = explode(' ', $match);
}
现在您将在$plugins
中看到以下内容:
Array
(
[0] => Array
(
[0] => PluginName
[1] => param1=value1
[2] => param2=value2
)
[1] => Array
(
[0] => BestSellers
[1] => limit=5
[2] => fromCategory=123
)
)
你想得到什么样的模式?在preg_匹配中你得到了什么?抱歉,兄弟,但你在“或更好”中描述的是不可能的。在regexp中不能有可变数量的匹配组。请参阅以获得解释。@GeoffreyBachelet:如果已知参数的最大数量,则可能。(一般情况下不可能).嗯,是的,我想(可能是错的)OP示例中的参数数量是任意的谢谢你的回答,但它在第二个@之后和之前返回所有内容。不幸的是,这不是我想要的。@BenFransen:你可以稍后进行额外处理。我甚至不知道PluginName中允许的字符,所以我最多只能将正则表达式修改为capt我知道,但我想知道这是否可以在正则表达式中完成(请参阅更新的问题以获取示例)。否则,我总是可以通过分解字符串来处理字符串。PluginName允许的字符是[a-zA-Z0-9]
@BenFransen:编辑了我的答案。这很好!它满足了我的要求,但还有一个问题。是否也可以选择参数部分?不是每个插件都定义了参数。或者我应该调用2个正则表达式并检查它是否有参数?基本上它还应该能够找到@include_plugin:SomePlugin@
谢谢谢谢你的帮助!我用了一个preg_match_all来得到我想要的,因为可以有多个插件include.+1并被接受。@BenFransen没问题。当然,一个preg_match_all
和一个循环就可以了。不,但是谢谢你的努力。看Mathieuw的回答,那一个做了我想做的事,只需要1个额外的(未提及要求):查找未定义参数的匹配项。感谢您的帮助,+1感谢您的贡献。非常清楚!感谢+1,接受转到Mathieu。
Array
(
[0] => Array
(
[0] => @include_plugin:PluginName param1=value1 param2=value2@
[1] => @include_plugin:BestSellers limit=5 fromCategory=123@
)
[1] => Array
(
[0] => PluginName param1=value1 param2=value2
[1] => BestSellers limit=5 fromCategory=123
)
)
$plugins = array();
foreach ($matches[1] as $match) {
$plugins[] = explode(' ', $match);
}
Array
(
[0] => Array
(
[0] => PluginName
[1] => param1=value1
[2] => param2=value2
)
[1] => Array
(
[0] => BestSellers
[1] => limit=5
[2] => fromCategory=123
)
)