【问题标题】:Flatten array of regular expressions展平正则表达式数组
【发布时间】:2018-10-26 07:00:39
【问题描述】:

我有一个正则表达式数组 -$toks:

Array
(
    [0] => /(?=\D*\d)/
    [1] => /\b(waiting)\b/i
    [2] => /^(\w+)/
    [3] => /\b(responce)\b/i
    [4] => /\b(from)\b/i
    [5] => /\|/
    [6] => /\b(to)\b/i
)

当我试图将其展平时:

$patterns_flattened = implode('|', $toks); 

我得到一个正则表达式:

/(?=\D*\d)/|/\b(waiting)\b/i|/^(\w+)/|/\b(responce)\b/i|/\b(from)\b/i|/\|/|/\b(to)\b/i

当我尝试:

if (preg_match('/'. $patterns_flattened .'/', 'I'm waiting for a response from', $matches)) {
    print_r($matches);  
}
  • 我收到一个错误:

    警告:preg_match(): Unknown modifier '(' in ...index.php on line

我的错误在哪里? 谢谢。

【问题讨论】:

  • 你的正则表达式需要在//之间,所以你需要从数组的每个值中删除//,同时删除表示不区分大小写的“i”,并将它放在//i之后,并且/implode()/i 之间的数组内爆的所有数据
  • @user889349 为什么不循环数组并测试每个正则表达式?
  • @splash58 那会慢很多,恕我直言
  • 但是 OP 现在应该确保删除诸如 /i 之类的选项不会改变正则表达式的逻辑。

标签: php arrays regex preg-match-all


【解决方案1】:

你需要去掉开头和结尾的斜杠,像这样:

$toks = [
    '(?=\D*\d)',
    '\b(waiting)\b',
    '^(\w+)',
    '\b(response)\b',
    '\b(from)\b',
    '\|',
    '\b(to)\b',
];

然后,我想你会想使用preg_match_all 而不是preg_match

$patterns_flattened = implode('|', $toks);
if (preg_match_all("/$patterns_flattened/i", "I'm waiting for a response from", $matches)) {
    print_r($matches[0]);
}

如果您获取第一个元素而不是所有元素,它将返回每个正则表达式的全部匹配项:

Array
(
    [0] => I
    [1] => waiting
    [2] => response
    [3] => from
)

Try it on 3v41.org

【讨论】:

    【解决方案2】:
       <?php
    
    $data = Array
    (
    0 => '/(?=\D*\d)/',
    1 => '/\b(waiting)\b/i',
    2 => '/^(\w+)/',
    3 => '/\b(responce)\b/i',
    4 => '/\b(from)\b/i',
    5 => '/\|/',
    6 => '/\b(to)\b/i/'
    );
    
    
    $patterns_flattened = implode('|', $data);
    
    $regex = str_replace("/i",'',$patterns_flattened);
    $regex = str_replace('/','',$regex);
    
    if (preg_match_all(  '/'.$regex.'/', "I'm waiting for a responce from", $matches)) {
        echo '<pre>';
    print_r($matches[0]);
    }
    

    您必须从正则表达式中删除斜杠以及 i 参数才能使其正常工作。这就是它破裂的原因。

    真正验证您的正则表达式的一个非常好的工具是:

    https://regexr.com/

    当我必须制作比平常更大的正则表达式时,我总是使用它。

    以上代码的输出是:

      Array
    (
        [0] => I
        [1] => waiting
        [2] => responce
        [3] => from
    )
    

    【讨论】:

      【解决方案3】:

      需要对您的 $tok 数组进行一些调整。

      1. 要消除错误,您需要从每个数组元素中删除模式分隔符和模式修饰符。
      2. 没有必要进行捕获分组,事实上,这会导致更高的步数并造成不必要的输出数组膨胀。
      3. 无论您对(?=\D*\d) 的意图是什么,都需要重新考虑。如果您的输入字符串中的任何地方都有一个数字,您可能会生成许多空元素,这些元素肯定不会对您的项目产生任何好处。 Look at what happens 当我在你的输入字符串中在from 之后放置一个空格然后 1 时。

      这是我的建议:(PHP Demo)

      $toks = [
          '\bwaiting\b',
          '^\w+',
          '\bresponse\b',
          '\bfrom\b',
          '\|',
          '\bto\b',
      ];
      
      $pattern = '/' . implode('|', $toks) . '/i';
      var_export(preg_match_all($pattern, "I'm waiting for a response from", $out) ? $out[0] : null);
      

      输出:

      array (
        0 => 'I',
        1 => 'waiting',
        2 => 'response',
        3 => 'from',
      )
      

      【讨论】:

        猜你喜欢
        • 2020-02-09
        • 1970-01-01
        • 1970-01-01
        • 2016-12-07
        • 2013-06-04
        • 2021-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多