首页 > 解决方案 > PHP preg_match_all - 以不同的顺序从模式中提取内容

问题描述

我正在清理我的代码中的一些 wordpress 短代码,并且我正在寻找一种无论值的顺序如何都能提取正确值的解决方案。

例子:

[Links label="my_label" url="my_url" external="other_value"]

如果我想提取 my_label、my_url 和 other_value,我会使用以下结构:

preg_match_all('/\[Links label=\"(.*?)\" url=\"(.*?)\" external=\"(.*?)\"\]/', $content, $output_array);

问题是我有时会有这样的不同顺序:

[Links url="my_url" external="other_value" label="my_label"]

我以前的 preg_match_all 不适用于此。我试图将每个模式放在 (...) 之间或使用 | 但我没有得到预期的结果。我在这里看到了识别字符串的解决方案,但我需要的不仅仅是识别字符串,我还需要提取值。

对于正则表达式专家来说,这可能是微不足道的。

谢谢

标签: phpregexpreg-match-all

解决方案


如果属性也可以是任何顺序的不同数量并且应该以 开头[Links ,则可以使用\G锚。键在捕获组 1 中,值在捕获组 2 中。

(?:\[Links|\G(?!^))(?=[^][]*])\h+([^\s=]+)="([^\s"]+)"

解释

  • (?:非捕获组
    • \[Links匹配[Links
    • |或者
    • \G(?!^)在上一场比赛结束时断言位置,而不是在开始时
  • )关闭非捕获组
  • (?=[^][]*])]正向前瞻,在右边断言 a
  • \h+匹配 1+ 个水平空白字符
  • (捕获组 1
    • [^\s=]+匹配除=空格字符以外的任何字符的 1 次以上
  • )关闭组 1
  • ="从字面上匹配
  • (捕获组 2
    • [^\s"]+匹配除"空格字符以外的任何字符的 1 次以上
  • )"关闭第 2 组并匹配"

正则表达式演示

例子

$re = '/(?:\[Links|\G(?!^))(?=[^][]*])\h+([^\s=]+)="([^\s"]+)"/m';
$str = '[Links label="my_label" url="my_url" external="other_value"]';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
print_r($matches);

输出

Array
(
    [0] => Array
        (
            [0] => [Links label="my_label"
            [1] => label
            [2] => my_label
        )

    [1] => Array
        (
            [0] =>  url="my_url"
            [1] => url
            [2] => my_url
        )

    [2] => Array
        (
            [0] =>  external="other_value"
            [1] => external
            [2] => other_value
        )

)

php演示


推荐阅读