【问题标题】:regexp split string by commas and spaces, but ignore the inside quotes and parentheses正则表达式用逗号和空格分割字符串,但忽略内部引号和括号
【发布时间】:2010-11-25 07:34:16
【问题描述】:

我需要用逗号和空格分割字符串,但忽略内引号、单引号和括号

$str = "Questions, \"Quote\",'single quote','comma,inside' (inside parentheses) space #specialchar";

这样结果数组就会有

[0]问题 [1]报价 [2]单引号 [3]逗号,内 [4]括号内 [5]空间 [6]#特殊字符

我的正则表达式是

$tags = preg_split("/[,\s]*[^\w\s]+[\s]*/", $str,0,PREG_SPLIT_NO_EMPTY);

但这忽略了特殊字符,仍然将逗号分隔在引号内,结果数组是:

[0]问题 [1]报价 [2]单引号 [3]逗号 [4]里面 [5]括号内 [6]空间 [7]特殊字符

ps:这不是 csv

非常感谢

【问题讨论】:

    标签: php regex


    【解决方案1】:

    这仅适用于非嵌套括号:

        $regex = <<<HERE
        /  "  ( (?:[^"\\\\]++|\\\\.)*+ ) \"
         | '  ( (?:[^'\\\\]++|\\\\.)*+ ) \'
         | \( ( [^)]*                  ) \)
         | [\s,]+
        /x
        HERE;
    
        $tags = preg_split($regex, $str, -1,
                             PREG_SPLIT_NO_EMPTY
                           | PREG_SPLIT_DELIM_CAPTURE);
    

    ++*+ 将尽可能多地消耗,并且不会为回溯提供任何回报。这种技术在perlre(1) 中被描述为进行这种匹配的最有效方法。

    【讨论】:

    • 因莎拉。你知道在 javascript split() 函数中使用相同的正则表达式吗?如果你能告诉我就好了。
    • @unknown,我认为/x 标志和*+++ 量词可能不受支持,因此,丢失/x 标志并去除任何空格(包括换行符),而不是*+++ 量词分别只使用*+
    【解决方案2】:

    嗯,这适用于您提供的数据:

    $rgx = <<<'EOT'
    /
      [,\s]++
      (?=(?:(?:[^"]*+"){2})*+[^"]*+$)
      (?=(?:(?:[^']*+'){2})*+[^']*+$)
      (?=(?:[^()]*+\([^()]*+\))*+[^()]*+$)
    /x
    EOT;
    

    前瞻断言,如果在当前匹配位置之前有任何双引号、单引号或括号,则它们的数量是偶数,并且括号是平衡的对(不允许嵌套)。这是确保当前匹配不会出现在一对引号或括号内的一种快速而简单的方法。

    当然,它假设输入格式正确。但是关于格式良好的主题,引号中的转义引号呢?如果您在括号内有引号怎么办,反之亦然?这种输入是否合法?

    "not a \" quote", 'not a ) quote', (not ",' 引号)

    如果是这样,那么你面临的工作要困难得多。

    【讨论】:

      猜你喜欢
      • 2013-05-19
      • 1970-01-01
      • 2017-09-02
      • 2017-04-07
      • 1970-01-01
      • 2017-11-25
      • 1970-01-01
      • 2020-04-05
      • 1970-01-01
      相关资源
      最近更新 更多