其他分享
首页 > 其他分享> > 如何判断传递给preg_match()的模式中是否使用了PREG命名组?

如何判断传递给preg_match()的模式中是否使用了PREG命名组?

作者:互联网

我有兴趣确定是否在传递给preg_match()的模式中使用了命名组.

想象一下一个场景,其中迭代了一个正则表达式模式列表并传递到preg_match()中.类似于以下内容:

$trg = "123abc/4";
$patterns = array('/abc/', '/abc\/(\d+)/', '/abc\/(?P<id>\d+)/');
foreach ($patterns as $p) {
   preg_match($p, $trg, $matches);
   if (len($matches) > 0) {
      // Do something interesting with the capture
   } 
}

如果找到匹配项,则$matches中将至少有一个元素.最后两个模式包含一个捕获,但是$matches在第一种情况下将是一个两个元素的数组,
最后是三个元素的数组.

我想知道,如果不使用模式,是否使用了命名组.我需要知道这一点,因为我想将捕获的文本传递给其他函数.

可以想象,模式只有在运行时才能知道,因此我不能简单地查看匹配项中的元素数量.

关于如何解决这个问题的任何想法?

谢谢你的时间.

解决方法:

定制的is_assoc函数呢?由于PHP不能区分列表和哈希,因此我发现它在其他情况下也很有用.

<?php
function is_assoc(&$arr) {
    return array_keys($arr) !== range(0, count($arr) - 1);
}
if (preg_match('/(?P<foo>foo)/', 'foo', $match) && is_assoc($match)) {
    echo "yep, it had named groups";
}

它缺乏在PHP的标准库中已经具有用于该目的的功能的“清洁度”(我知道),但是实际的if语句仍然非常紧凑且可读性强.

我知道您的示例可能只代表程序的一小部分,但是在我看来,所有模式都是您手动编写的,并且存在于代码中,因此您始终知道哪些模式将返回命名组,因为您将命名组组在那里.您难道不就将foreach(以$p的图案作为$p)更改为foreach(以$i => $p的图案),并在找到匹配项时检查$i的值吗?

标签:preg-match,php
来源: https://codeday.me/bug/20191208/2095049.html