解析CSV不同的模式

时间:2015-11-02 20:26:43

标签: ruby-on-rails ruby regex

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

这是3种不同的模式。

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

我必须将这个正则表达式传递给ruby split方法。

line.split(/regular_expression/)

如果逗号是文本的一部分,那么当有逗号时(例如在第二个表达式中)可以分割测试

感谢

2 个答案:

答案 0 :(得分:2)

在这种情况下,请勿尝试拆分引号之间未包含的每个逗号。尝试使用此模式查找所有不是逗号或引号之间的内容:

"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"]] 

答案 1 :(得分:0)

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

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"]]