【问题标题】:How to split a string by colons NOT in quotes如何用冒号而不是引号分割字符串
【发布时间】:2011-06-25 14:22:14
【问题描述】:

我有一个用冒号分隔的 CSV 文件,但它包含用引号括起来的文本字段,而引号本身包含多个冒号。

我想要一个简单的解决方案来获取数据字段,但是例如。在 ruby​​ 中,split 方法在每个冒号上拆分。

是否有匹配所有冒号的正则表达式,除了用引号括起来的冒号?

【问题讨论】:

  • 您考虑过使用 CSV 解析器吗?
  • +1 用于使用 CSV 解析器。这是比看起来要困难得多的任务之一,并且有人已经为您完成了所有工作。
  • FasterCSV 是一个我很幸运的替代解析器。
  • @jleedev FasterCSV 现在是 Ruby 1.9 标准库中的 CSV

标签: ruby regex csv


【解决方案1】:

给定:

str = 'foo:bar:"jim:jam":jar'

你可以这样做:

a = str.scan( /([^":]+)|"([^"]+)"/ ).flatten.compact
p a
#=> ["foo", "bar", "jim:jam", "jar"]

或者你可以这样做:

a = []
str.scan( /([^":]+)|"([^"]+)"/ ){ a << ($1 || $2) }
p a
#=> ["foo", "bar", "jim:jam", "jar"]

那些正则表达式说要找到任一

  • 一个或多个字符不是引号或冒号,
  • 引号,后跟一个或多个非引号字符。

【讨论】:

  • 也许将 "([^"]+)" 更改为 "((?:""|[^"])+)" 以便转义引号也得到匹配。
  • 魔术!但是,上面的一个问题是:考虑使用双冒号的修改后的字符串 'foo::bar:"jim:jam":jar'。不会匹配。
  • @user613159 然后你应该看到@DGM 的回答。
  • 您可以添加另一种方法来处理空字段:|((?&lt;=^|:)(?=:|$))
【解决方案2】:

【讨论】:

【解决方案3】:

你可以用双引号而不是冒号分割

>> str = 'foo:bar:"jim:jam":jar'
=> "foo:bar:\"jim:jam\":jar"
>> str.split("\"").each_with_index do |x,y|
?>  puts y%2==0 ? x.split(":") : x
>> end
foo
bar
jim:jam

jar

【讨论】:

    【解决方案4】:

    第一次尝试太糟糕了,修改了整个事情。这是我的正则表达式解决方案:

    获取最后一个分隔符字段':' = :last
    修剪:/(?:^\s*:|:|^)\s*(".*?"|.*?)(?=\s*(?:\:|$))/
    无修剪:/(?:(?&lt;!^):|^)(\s*".*?"\s*|.*?)(?=\:|$)/

    ------

    获取第一个和最后一个分隔符字段':' = first:last
    修剪:/(?:^|:)\s*(".*?"|(?&lt;!^).*?|)(?=\s*(?:\:|$))/
    没有修剪:/(?:^|:)(\s*".*?"\s*|\s*(?&lt;!^).*?|)(?=\:|$)/

    是的,它并不像人们想象的那么容易..

    【讨论】:

      猜你喜欢
      • 2016-01-07
      • 2011-03-26
      • 2022-01-17
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2021-06-12
      • 2013-04-22
      相关资源
      最近更新 更多