2011-06-01 171 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)