【问题标题】:Trying to split string into single words or "quoted words", and want to keep the quotes in the resulting array试图将字符串拆分为单个单词或“引用的单词”,并希望将引号保留在结果数组中
【发布时间】:2012-07-18 22:44:47
【问题描述】:

我正在尝试将Presentation about "Test Driven Development" 之类的字符串拆分为这样的数组:

[ 'Presentation',
  'about',
  '"Behavior Driven Development"' ]

我试过CSV::parse_line(string, col_sep: ' '),但结果是

[ 'Presentation',
  'about',
  'Behavior Driven Development' ] # I'm missing the quotes here

我也尝试了一些正则表达式魔法,但我还是个初学者,没有成功。我想这对于专业人士来说很简单,所以也许有人可以指出我正确的方向?谢谢。

【问题讨论】:

  • 我修正了我的答案。它现在应该适合你了。
  • 哈! CSV 实际上正是我所需要的。

标签: ruby regex csv


【解决方案1】:

您可以使用以下正则表达式split

str = 'Presentation about "Test Driven Development"'
p str.split(/\s(?=(?:[^"]|"[^"]*")*$)/)
# => ["Presentation", "about", "\"Test Driven Development\""]

如果有空格,则它会拆分,但前提是直到末尾的文本包含偶数个 "。请注意,只有正确引用所有字符串时,此版本才有效。

另一种解决方案使用scan 读取字符串的各个部分(除了空格):

p str.scan(/(?:\w|"[^"]*")+/)
# => ["Presentation", "about", "\"Test Driven Development\""]

【讨论】:

  • 谢谢你,就像一个魅力!正则表达式很神奇...我会尝试剖析它们并理解它。
  • 供您参考,我用它来删除空元素并去除引号和空格: "ab 'cd '".split(/\s(?=(?:[^'"]|' [^']*'|"[^"]*")*$)/).select {|s|不是s.empty? }.map {|s| s.gsub(/(^ +)|( +$)|(^["']+)|(["']+$)/,'')}
【解决方案2】:

只是为了扩展霍华德先前的答案,您可以添加此方法:

class String
  def tokenize
    self.
      split(/\s(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/).
      select {|s| not s.empty? }.
      map {|s| s.gsub(/(^ +)|( +$)|(^["']+)|(["']+$)/,'')}
  end
end

结果:

> 'Presentation      about "Test Driven Development"  '.tokenize
=> ["Presentation", "about", "Test Driven Development"]

【讨论】:

    【解决方案3】:

    这里:

    "Presentation about \"Test Driven Development\"".scan(/\s?\w+\s?|"[\w\s]*"/).map {|s| s.strip}
    

    【讨论】:

    • 很好,删除了我的 -1。请注意,现在空格已包含在结果中。
    • .scan(/(?:\S|"[^"]*")+/) 呢?
    • 谢谢!有趣的是,有多少种不同的方法可以解决一个问题。
    猜你喜欢
    • 1970-01-01
    • 2014-11-28
    • 2011-01-13
    • 2017-07-03
    • 2018-05-27
    • 1970-01-01
    • 2011-10-23
    • 2014-06-29
    相关资源
    最近更新 更多