将字符串按逗号拆分成数组,除非逗号在引号内

6

给定一个 Ruby 中的字符串数组,其中一些带有逗号的项在引号中:

my_string.inspect
# => "\"hey, you\", 21"

如何获取一个数组:

["hey, you", " 21"] 

7
最好使用现有的CSV库。编写CSV解析器比人们想象的更麻烦。 - Dave Newton
1
@DaveNewton 谢谢!我查阅了 Ruby CSV 库,“string”。parse_csv 给了我想要的结果。 - steel
2个回答

7
Ruby 标准 CSV 库的 .parse_csv 方法可以完成这个任务。
require 'csv'
"\"hey, you\", 21".parse_csv
# => ["hey, you", " 21"] 

1
据我所见,String#parse_csv已经被弃用(自v1.9.2起),在这种情况下,您应该使用CSV::parse_line(即require 'csv'; CSV.parse_line("\"hey, you\", 21))。你知道是不是这样吗? - Cary Swoveland
@CarySwoveland 看起来 String #parse_csv 在 Ruby 2.2.3 中仍然活跃。http://www.rubydoc.info/stdlib/csv/String%3Aparse_csv 和 http://ruby-doc.org/stdlib-2.2.3/libdoc/csv/rdoc/CSV.html - steel
@CarySwoveland 我在 Ruby 2.5.1 中无法使用 .parse_csv。我真的认为你应该将你的 CSV.parse_line 输入为单独的答案,这样你就能得到应得的信用了。这样做,然后回复我,我会很乐意给它点赞。 - ReggieB
1
@ReggieB,你是否require 'csv'(假设你有很好的记忆力)。这会导致parse_csv被添加到String的实例方法中。 - Cary Swoveland

3

是的,使用CSV::parse_lineString#parse_csv(这两者都需要在代码中添加require 'csv'以使用),是解决此处问题的方式,但也可以使用正则表达式:

r = /
    (?:     # Begin non-capture group
    (?<=\") # Match a double-quote in a positive lookbehined
    .+?     # Match one or more characters lazily
    (?=\")  # Match a double quote in a positive lookahead.
    )       # End non-capture group
    |       # Or
    \s\d+   # Match a whitespace character followed by one or more digits
    /x      # Extended mode

str = "\"hey, you\", 21"
str.scan(r)
  #=> ["hey, you", " 21"]

如果您希望"21"而不是" 21",只需删除\s即可。

1
我会点赞这个,但这似乎表明我赞同复杂的正则表达式,而事实上我认为CSV.parse_line是最好的解决方案。我认为你应该把这个答案分成两部分(正则表达式版本很有趣,可能在某些情况下有帮助)。 - ReggieB
关于你的第一个观点,我的看法是,即使代码片段(无论多么复杂)不能代表最佳解决问题的方式,只要它有助于教育读者,就具有价值。#2:虽然@steel的答案没有使用parse_line,但我对他的回答的评论应该足以告知读者该方法,这就是我关心的全部。在我看来,那个评论并不算作一个独立的答案。 - Cary Swoveland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接