Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 正则表达式以获取匹配中的重复匹配_Php_Regex_Preg Match All - Fatal编程技术网

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
        )

)