代码之家  ›  专栏  ›  技术社区  ›  Leon Segal

php preg_split忽略重复的分隔符

  •  0
  • Leon Segal  · 技术社区  · 4 年前

    我想拆分我们只能使用的旧版本phpstan(v0.9)生成的字符串。

    每个错误字符串由以下字符分隔 : ,但有时会有标记为的静态调用 :: 我想忽略这一点。

    我的代码:

    $error = '/path/to/file/namespace/filename:line_number:error message Namespace\ClassName::method().'
    $output = preg_split('/:/', $error);
    

    A. var_dump 属于 $output 给出以下内容:

    Array
    (
        [0] => /path/to/file/namespace/filename
        [1] => line_number
        [2] => error message Namespace\ClassName
        [3] => 
        [4] => method().
    )
    

    我想要的结果是:

    Array
    (
        [0] => /path/to/file/namespace/filename
        [1] => line_number
        [2] => error message Namespace\ClassName::method().
    )
    

    我希望这可以用正则表达式来解决。

    我一直在阅读类似的问题,并尝试了正则表达式的变体,但都不起作用。

    0 回复  |  直到 4 年前
        1
  •  2
  •   Community iksemyonov    4 年前

    您可以使用前瞻和回顾来进行拆分:

    $error = '/path/to/file/namespace/filename:line_number:error message Namespace\ClassName::method().';
    $arr = preg_split('/(?<!:):(?!:)/', $error, -1, PREG_SPLIT_NO_EMPTY);
    print_r($arr);
    
    Array
    (
        [0] => /path/to/file/namespace/filename
        [1] => line_number
        [2] => error message Namespace\ClassName::method().
    )
    

    RegEx Demo

    RegEx详细信息:

    • (?<!:) :如果有一场比赛,消极的回头看会让比赛失败 : 后面
    • : :匹配a :
    • (?!:) :如果有一场比赛失败,那将是消极的 : 向前地
        2
  •  1
  •   The fourth bird    4 年前

    另一种选择是匹配2次或更多次 : 和使用 (*SKIP)(*F) 。然后匹配一个单曲 : 分裂。

    :{2,}(*SKIP)(*F)|:
    

    解释

    • :{2,}(*SKIP)(*F) 匹配2次或更多次 : ,然后跳过当前匹配的所有字符
    • | 或者
    • : 匹配单曲 :

    Regex demo | Php demo

    $error = '/path/to/file/namespace/filename:line_number:error message Namespace\ClassName::method().';
    $output = preg_split('/:{2,}(*SKIP)(*F)|:/', $error);
    print_r($output);
    

    输出

    Array
    (
        [0] => /path/to/file/namespace/filename
        [1] => line_number
        [2] => error message Namespace\ClassName::method().
    )
    
        3
  •  0
  •   Casimir et Hippolyte    4 年前

    使用 preg_match_all (有时更容易拆分):

    preg_match_all('~[^:]+(?>::[^:]*)*~', $error, $matches);
    
    print_r($matches[0]);