2011-06-01 136 views
11

多个分隔符的字符串举个例子,我有一个这样的字符串:拆分与红宝石

options = "Cake or pie, ice cream, or pudding" 

我希望能够通过or,,并且, or分裂的字符串。

的事情是,是,我已经能够做到这一点,但只有通过解析,, or第一,然后在or分裂每个数组项,扁平化合成阵列事后这样:

options = options.split(/(?:\s?or\s)*([^,]+)(?:,\s*)*/).reject(&:empty?); 
options.each_index {|index| options[index] = options[index].sub("?","").split(" or "); } 

结果数组是这样的:["Cake", "pie", "ice cream", "pudding"]

是否有更高效(或更容易)的方式来分割我的字符串在这三个分隔符?

回答

14

有关以下内容:

options.gsub(/ or /i, ",").split(",").map(&:strip).reject(&:empty?) 
  • 替换所有的分隔符,但,
  • 拆分它在,
  • 剪裁每个字符,因为这样的东西ice cream与一家领先的空间可能会留
  • 删除所有空白字符串
+2

看起来更容易阅读,尽管有两件事:一,'&:empty'应该改为'&:empty?'和二,''或''可以更改为'/或/ i'以容纳大写字母'OR'。 – Mark 2011-06-01 21:16:43

+0

非常感谢 - '&:empty'甚至不起作用,我确实用'&:empty?'来测试它。正则表达式也是一个很方便的补充。 – mabako 2011-06-01 21:30:11

9

首先,你的方法可以简化一点与Array#flatten

>> options.split(',').map{|x|x.split 'or'}.flatten.map(&:strip).reject(&:empty?) 
=> ["Cake", "pie", "ice cream", "pudding"] 

我宁愿使用一个正则表达式:

>> options.split /\s*, or\s+|\s*,\s*|\s+or\s+/ 
=> ["Cake", "pie", "ice cream", "pudding"] 

可以使用|在正则表达式给出的替代品,并且首先保证它不会产生空的项目。用正则表达式捕获空白可能是最有效的,因为你不必再次扫描数组。

由于Zabba指出的那样,你可能还是要拒绝空项目,促使该解决方案:

>> options.split(/,|\sor\s/).map(&:strip).reject(&:empty?) 
=> ["Cake", "pie", "ice cream", "pudding"] 
+1

如果字符串由于某种原因以'或or开头?然后你的正则表达式会产生空白/空字符串。 – Zabba 2011-06-01 20:43:33

+2

嗯,我们确实想把它当作分隔符。开头的分隔符表示一个空的项目。但我会解决它。 – 2011-06-01 20:48:44

+0

第二种解决方案存在一个问题,就是一个类似“smore's”的词产生了“[”sm“,”e's“]'。将正则表达式设为'/,| \ sor \ s /'可能会更好。 (也可以使用'i'模式来接受大写'OR')。 – Mark 2011-06-01 20:58:11

3

由于"or"","做同样的事情,最好的办法就是告诉多的情况下应该是正则表达式对待与单个案例相同:

options = "Cake or pie, ice cream, or pudding" 
regex = /(?:\s*(?:,|or)\s*)+/ 
options.split(regex)