代码之家  ›  专栏  ›  技术社区  ›  Bhaskar Dabhi

当逗号不在任何括号内时,用逗号分解字符串

  •  3
  • Bhaskar Dabhi  · 技术社区  · 7 年前

    我有字符串“xyz(text1,(text2,text3)),asd”,我想用它来分解,但唯一的条件是分解只能在 , 不在任何括号内(在这里 () )。

    我在stackoverflow上看到了许多这样的解决方案,但它不符合我的模式。( example1 )( example2 )

    我的模式的正确正则表达式是什么?

    就我而言 xyz(text1,(text2,text3)),asd

    结果应为

    xyz(text1,(text2,text3)) asd

    2 回复  |  直到 7 年前
        1
  •  1
  •   Wiktor Stribiżew    7 年前

    您可以使用匹配方法,使用带有 subroutine :

    preg_match_all('~\w+(\((?:[^()]++|(?1))*\))?~', $s, $m)
    

    请参见 regex demo

    详细信息

    • \w+ -1个以上字符
    • (\((?:[^()]++|(?1))*\))? -可选的捕获组匹配
      • \( -a (
      • (?:[^()]++|(?1))* -零次或多次出现
        • [^()]++ -1个以上字符,除 ( )
        • | -或
        • (?1) -全组1模式
      • \) -a )

    PHP demo :

    $rx = '/\w+(\((?:[^()]++|(?1))*\))?/';
    $s = 'xyz(text1,(text2,text3)),asd';
    if (preg_match_all($rx, $s, $m)) {
        print_r($m[0]);
    }
    

    输出:

    Array
    (
        [0] => xyz(text1,(text2,text3))
        [1] => asd
    )
    
        2
  •  1
  •   bobble bubble    7 年前

    如果要求在 , 但只有在嵌套括号外,另一个想法是使用 preg_split skip 括号中的内容也可以使用 recursive pattern

    $res = preg_split('/(\((?>[^)(]*(?1)?)*\))(*SKIP)(*F)|,/', $str);
    

    See this pattern demo at regex101 或a PHP demo at eval.in

    管道字符的左侧用于匹配和跳过括号内的内容。
    在右侧,它将匹配括号外剩余的逗号。

    所使用的模式是不同常见模式的变体,以匹配嵌套的父项。