平整正则表达式数组

时间:2018-10-26 07:00:40

标签: php arrays regex preg-match-all

我有一个正则表达式数组-$ 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():... index.php行上的未知修饰符'('

我的错误在哪里? 谢谢。

3 个答案:

答案 0 :(得分:2)

您需要删除开始斜杠和结束斜杠,如下所示:

$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

答案 1 :(得分: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
)

答案 2 :(得分:0)

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

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

这是我的建议:(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',
)