加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 正则表达式可选重复组

发布时间:2020-12-13 17:01:17 所属栏目:PHP教程 来源:网络整理
导读:假设以下字符串: 这里有一些文字[baz | foo]和这里[foo | bar | baz]甚至这里[选项]. 我只能通过这个丑陋的正则表达式(Regex101.com demo)得到匹配: /(?: [ (?: |? ([^|[]]+) )? (?: |? ([^|[]]+) )? (?: |? ([^|[]]+) )? ])/ugx 关键是我需
假设以下字符串:

这里有一些文字[baz | foo]和这里[foo | bar | baz]甚至这里[选项].

我只能通过这个丑陋的正则表达式(Regex101.com demo)得到匹配:

/(?:
  [
    (?:
      |?
      ([^|[]]+)
    )?
    (?:
      |?
      ([^|[]]+)
    )?
    (?:
      |?
      ([^|[]]+)
    )?
  ]
)/ugx

关键是我需要用方括号分组匹配.
所以目前我确实有我需要的结果:

[
  {
    "match": 1,"children": [
      {
        "group": 1,"start": 16,"end": 19,"value": "baz"
      },{
        "group": 2,"start": 20,"end": 23,"value": "foo"
      }
    ]
  },{
    "match": 2,"start": 35,"end": 38,"value": "foo"
      },"start": 39,"end": 42,"value": "bar"
      },{
        "group": 3,"start": 43,"end": 46,"value": "baz"
      }
    ]
  },{
    "match": 3,"start": 63,"end": 69,"value": "option"
      }
    ]
  }
]

结果是正确的,但正则表达式仅限于模式中重复块的数量.
是否有一些解决方法使其匹配sqare括号内的所有选项?

解决方法

您将无法在模式中递归生成捕获组,因为引擎不会为您提供此类功能.说,你有两个选择:

>根据管道的出现次数构建正则表达式
|在您的输入字符串中.

通过这种方式,您可以构建一个具有([^] [|])重复模式的单一正则表达式,它们可以根据需要进行组匹配:

$pattern = (function () use ($string) {
    $array = [];
    for ($i = 0; $i <= substr_count($string,"|"); $i++) {
        $array[] = $i == 0 ? '([^][|]+)' : '([^][|]+)?';
    }
    return implode("|?",$array);
})();

通过给出一个输入字符串,如:

some text here [baz] and here [you|him|her|foo|bar|baz|foo|option|test] and even here [another].

煮熟的正则表达式将是:

~[([^][|]+)|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?|?([^][|]+)?]~

Live demo

然后你可以简单地使用它:

preg_match_all("~[$pattern]~",$string,$matches,PREG_SET_ORDER);

Live demo

这是一种解决方法,可以显示您可以节省时间并避免在构建正则表达式时遇到麻烦,而正则表达式并不是一个简单易用的解决方案.

>受益于其他语言功能.

以上解决方法没有带来可靠的解决方案.它正在做很多不需要的工作.下面的代码确实适合这项工作:

// Capture strings between brackets
preg_match_all('~[([^]]+)]~',$matches);

$groups = [];

foreach ($matches[1] as $values) {
    // Explode them on pipe
    $groups[] = explode('|',$values);
}

输出将是:

Array
(
    [0] => Array
        (
            [0] => baz
        )

    [1] => Array
        (
            [0] => you
            [1] => him
            [2] => her
            [3] => foo
            [4] => bar
            [5] => baz
            [6] => foo
            [7] => option
            [8] => test
        )

    [2] => Array
        (
            [0] => another
        )

)

Live demo

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读