PHP preg_match_all捕获字符串前面的所有模式,而不是中间字符串


PHP preg_match_all capture all patterns at front of string not mid string

给定主题

AB: CD:DEF: HIJ99:message packet - no capture

我精心制作了以下正则表达式以正确捕获 2-5 个字符的目标,这些目标后跟一个冒号。

/'s{0,1}([0-9a-zA-Z]{2,5}):'s{0,1}/

即使目标之前或之后添加了错误的空格,也会返回我的匹配项

[0] => AB
[1] => CD
[2] => DEF
[3] => HIJ99

但是,如果消息数据包在任何地方都包含冒号,例如

AB: CD:DEF: HIJ99:message packet no capture **or: this either**

当然,它在结果集中包含[4] => or,这是不需要的。 我想从一开始就将匹配限制为连续集合,然后一旦我们失去并发性,就停止在剩余的匹配中寻找更多匹配

编辑 1:还尝试^('s{0,1}([0-9a-zA-Z]{2,5}):'s{0,1}){1,5}从字符串开头强制检查多个匹配项,但随后我丢失了单个匹配项

[0] => Array
    (
        [0] => AB: CD:DEF: HIJ99:
    )
[1] => Array
    (
        [0] => HIJ99:
    )
[2] => Array
    (
        [0] => HIJ99
    )

编辑 2:请记住,主题不是固定的。

AB: CD:DEF: HIJ99:message packet - no capture

可以同样容易

ZY:xw:VU:message packet no capture or: this either

对于我们试图拉动的比赛,主题也是可变的。 只是试图过滤掉匹配消息数据包中":"

的机会
您可以使用

'G进行连续的字符串匹配。

$str = 'AB: CD:DEF: HIJ99:message packet no capture or: this either';
preg_match_all('/'G's*([0-9a-zA-Z]{2,5}):'s*/', $str, $m);
print_r($m[1]);

输出:

Array
(
    [0] => AB
    [1] => CD
    [2] => DEF
    [3] => HIJ99
)

演示

怎么样:

$str = 'AB: CD:DEF: HIJ99:message packet no capture or: this either';
preg_match_all('/(?<![^:]{7})([0-9a-zA-Z]{2,5}):/', $str, $m);
print_r($m);

输出:

Array
(
    [0] => Array
        (
            [0] => AB:
            [1] => CD:
            [2] => DEF:
            [3] => HIJ99:
        )
    [1] => Array
        (
            [0] => AB
            [1] => CD
            [2] => DEF
            [3] => HIJ99
        )
)