【问题标题】:Parse CSV different patterns解析 CSV 不同的模式
【发布时间】:2016-02-02 20:16:21
【问题描述】:

我正在寻找的正则表达式必须能够处理不同的模式。

这是三种不同的模式。

"10.1234/altetric55,Awesome Steel Chair,1011-2513"
"\"Sporer, Kihn and Turner\",2885-6503"
"Bartell-Collins,1167-8230"

我必须将此正则表达式传递给 ruby​​ 拆分方法。

line.split(/regular_expression/)

这个想法是在有逗号时拆分测试,除非(如在第二个表达式中)逗号是文本的一部分

谢谢

【问题讨论】:

  • Regex to pick commas outside of quotes。它应该可以解决您的问题。
  • 请为三个字符串中的每一个显示您想要的输出。
  • CSV 解析器有什么问题?请参阅this IDEONE demothis one
  • @stribizhev 预期输出是 ["10.1234/altetric55", "Awesome Steel Chair", "1011-2513] ["Sporer, Kihn and Turner", "2885-6503"] ["Bartell -柯林斯”,“1167-8230”]
  • 我推荐使用 Ruby 内置的 CSV 类。它旨在处理您显示的那种逗号分隔值,包括那些在引号内嵌入逗号的值。不要尝试使用正则表达式,而是依赖预先编写的、经过良好测试的代码。

标签: ruby-on-rails ruby regex


【解决方案1】:

在这种情况下,不要尝试在没有被引号括起来的每个逗号上进行拆分。尝试找到使用此模式的引号之间不是逗号或内容的所有内容:

"10.1234/altetric55,Awesome Steel Chair,1011-2513".scan(/[^,"]*(?:"[^"\\]*(?:\\.[^"\\]*)*"[^,"]*)*/)

或避免空项目:

"10.1234/altetric55,Awesome Steel Chair,1011-2513".scan(/[^,"]+(?:"[^"\\]*(?:\\.[^"\\]*)*"[^,"]*)*|(?:"[^"\\]*(?:\\.[^"\\]*)*")+/)

但是您可以使用CSV 类避免这些复杂的问题:

require 'csv'
CSV.parse("\"Sporer, Kihn and Turner\",2885-6503")
=> [["Sporer, Kihn and Turner", "2885-6503"]] 

【讨论】:

  • 您是否重新打开了问题?为什么?
  • @stribizhev:是的,因为链接问题的答案中的所有解决方案都是,(?=stupid pattern to know if I am not between quotes until the end of the string)(如果字符串有点长,它将停止工作)。
  • 您在一两天前回答了几乎相同的问题,为什么不链接到您的答案?像这样的问题很烦人,一定有好的复制原件。
  • @CasimiretHippolyte ("10.1234/altetric55,Awesome Steel Chair,1011-2513").split(/[^,"]*(?:"[^"\\]*(?:\\.[^"\\]*)*"[^,"]*)*/ => /[^,"]*(?:"[^"\\]*(?:\\.[^"\\]*)*"[^,"]*)*/ pry(#<FileProcessor::Csv>)> => ["", ",", ","]我错过了什么吗?
  • 我的建议是使用 CSV 解析器。
【解决方案2】:

这是另一种方式,使用递归:

def split_it(str)
  outside_quotes = true
  pos = str.size.times.find do |i|
    case str[i]
    when '"'
      outside_quotes = !outside_quotes
      false
    when ','
      outside_quotes
    else false
    end
  end
  ret = pos ? [str[0,pos], *split_it(str[pos+1..-1])] : [str]
end

["10.1234/altetric55,Awesome Steel Chair,1011-2513",
"\"Sporer, Kihn and Turner\",2885-6503\",,,3\"",
"Bartell-Collins,1167-8230"].map { |s| split_it(s) }
  #=> [["10.1234/altetric55", "Awesome Steel Chair", "1011-2513"],
  #    ["\"Sporer, Kihn and Turner\"", "2885-6503\",,,3\""],
  #    ["Bartell-Collins", "1167-8230"]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 2010-09-24
    • 2013-10-16
    相关资源
    最近更新 更多