【问题标题】:Regex splitting strings on a character, not contained in ()正则表达式在字符上拆分字符串,不包含在 ()
【发布时间】:2009-02-18 22:14:29
【问题描述】:

我正在尝试在 a 上拆分一个字符串,其中该字符不包含在 () 中。

示例字符串:

`table1`.`lname`,`table1`.`fname`,if(foo is not null,foo,if(bar is not null,bar,table3.baz)),`table3`.`shu`

我想把它拆分成一个看起来像这样的数组

(
  0=>`table1`.`lname`
  1=>`table1`.`fname`
  2=>if(foo is not null,foo,if(bar is not null,bar,table3.baz))
  3=>`table3`.`shu`
)

关于如何解决这个问题的任何想法?

-- 戴夫

【问题讨论】:

    标签: regex


    【解决方案1】:

    一般来说,你不能用正则表达式来做到这一点。您通常需要一个递归后代解析器(或类似的东西)来匹配可能嵌套到任意深度的括号。

    我认为以前这里也有过类似的问题,但我很难找到它们。 This answer 不过应该有助于解释。

    【讨论】:

      【解决方案2】:

      我会查看您最喜欢的语言,看看是否有用于处理 CSV 文件的特定模块。 Ruby 有 CSV(在最近的版本中被 FasterCSV 取代)可以很好地处理您的问题。

      它比单个正则表达式更复杂,但可以完成工作。

      Perl 有 this Parse::CSV 模块。

      【讨论】:

        【解决方案3】:

        正则表达式在这方面不是很擅长。考虑以下 sn-p:

        (a)b(c(d)e)

        每个字母代表一个逗号(您的搜索目标)。根据您的问题,您只想匹配逗号b。诀窍是表达式通常要么贪婪要么不贪婪,没有中间地带。

        一个贪婪的表达式会在片段的开头看到(,在最后看到),并在其中获取所有内容,而不管其他地方是否有右括号。 没有会匹配。

        一个不贪婪的表达式将只取最小的集合,从头开始。它将匹配逗号b,但也将此段视为一个单元:(c(d),然后继续匹配逗号e

        有一些引擎可以让您计算嵌套级别,但表达式通常很难看且难以维护:最好避免使用该功能,除非您真正理解它。

        【讨论】:

          【解决方案4】:

          如果您知道您只会收到 一个 对括号,那么这可能会起作用:

          /(([^,]*\(.*\))|[^,]*)/g
          

          请记住,如果您在其他地方有 ),或者如果您有多个需要解析的括号,这将失败。

          【讨论】:

          • 他使用的例子有两对括号。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多