使用正则表达式解析字符串并获得所需的输出

Parse string with regex and get desired output

我想解析这个字符串

[[delay-4]]Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!

我需要这样的东西:

[
    [0] => '[[delay-4]]Welcome!',
    [1] => '[[delay-2]]Do you have some questions for us?',
    [2] => '[[delay-1]] Please fill input field!
];

字符串也可以是这样的(开头没有[[delay-4]]):

Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!

预期输出应该是这样的:

    [
        [0] => 'Welcome!',
        [1] => '[[delay-2]]Do you have some questions for us?',
        [2] => '[[delay-1]] Please fill input field!
    ];

我试过这个正则表达式 (https://regex101.com/r/Eqztl1/1/)

(?:\[\[delay-\d+]])?([\w \,?!.@#$%^&*()|`\]~\-='\"{}]+)

但是如果有人在文本中只写一个 [,我的正则表达式就会出现问题,正则表达式会失败,如果我包含 [ 来匹配,我会得到错误的结果。

谁能帮我解决这个问题?

你也可以在没有正则表达式的情况下做到这一点。

[[ 上展开并循环数组。如果项目的开头是 "delay" 然后添加 [[

$str = '[[delay-4]]Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!';

$arr = array_filter(explode("[[", $str));

foreach($arr as &$val){
    if(substr($val,0,5) == "delay") $val = "[[" . $val;
}

var_dump($arr);

https://3v4l.org/sIui1

按照你的模式

(?:[[delay-\d+]])?([\w \,?!.@#$%^&*()|`]~-='\"{}]+)

字符 class 中没有空缺 [。问题是,如果你添加它,你会得到你所说的错误结果。

这是因为经过延迟匹配后,现在包含[的下一部分字符class可以匹配其余字符,包括延迟部分的字符。

你可以做的是添加 [ 并使匹配非贪婪并结合正向前瞻来断言延迟部分的下一个匹配或字符串的末尾也匹配最后一个实例.

如果您不使用捕获组而只想要结果,则可以省略它。

(?:\[\[delay-\d+]])?[\w \,?!.@#$%^&*()|`[\]~\-='\"{}]+?(?=\[\[delay-\d+]]|$)

Regex demo | Php demo

两个更简单的操作可能是获得结果的途径:

$result = preg_replace('/\s*(\[\[delay-\d+]])/i', "\n", $subject);
$result = preg_split('/\r?\n/i', $result, -1, PREG_SPLIT_NO_EMPTY);

可以在运行这里看到: https://ideone.com/Z5tZI3 和这里: https://ideone.com/vnSNYI

这假定换行符没有特殊含义并且可以拆分。


更新:如以下评论中所述,单次拆分是可能的。

$result = preg_split('/(?=\[\[delay-\d+]])/i', $subject, -1, PREG_SPLIT_NO_EMPTY);

但是零长度匹配和正则表达式可能存在问题,您必须对此进行自己的研究。