2013-10-24 19 views
2

我需要一些完善正則表達式的建議。我試圖用一個表達式將一個字符串分成三部分。行來自一個文本文件中的格式如下所示:Ruby中的正則表達式在字符串中進行多重分割

25 red delicious apples at 0.75 

,其中第一部分是數量,第二個是項目名稱,第三個是每件的價格。我正在使用的代碼是這樣的:

File.open('basket.txt').each_line do |line| 
    item = line.split(/(\d+)\s|\sat\s/, 3) 

這將字符串分割,我想它,但它創建了一個項目數組長度爲4(第一索引包含nil)。我也想擺脫浮動結尾處的換行符。

+0

我個人很喜歡正則表達式,但我會不喜歡使用一個在這種情況下。我將只是做 '字= line.split' '量= words.shift' '價格= words.reverse.shift' '名= words.join(」「)' –

+0

哦,我忘了字符串中的'at'。那是我的第二個標記。 –

+0

在這種情況下,我將做到: '詞語= line.split;' '量= words.shift;' '價格= words.reverse.shift;' 'words.reverse.shift;' 'name = words.join(「」)' –

回答

2

我會使用匹配而不是拆分來完成此任務。這樣你就可以更準確地獲得組。舉例來說,如果我們假設有在產品的名稱沒有數字:

s = "25 red delicious apples 0.75" 
m = s.match(/(\d+) ([^\d.]+) ([\d.]+)/) 
m[1] 
=> "25" 
m[2] 
=> "red delicious apples" 
m[3] 
=> "0.75" 
+0

謝謝,我喜歡這種方法,但我不得不編輯字符串 - 裏面有'at'。我能否以某種方式拒絕'at'?我不太明白這個表達 - 中間如何捕獲字符串? –

+0

中間只捕獲數字和點。 –

+0

哦,我明白了。 ^這是否定的事情。哼。我喜歡這一點,除了我不知道如何消除'at',我可以堅持\ sat \ s的某個地方嗎? –

0
p "25 red delicious apples 0.75".partition(/[\D\s]+/) 
#=> ["25", " red delicious apples ", "0.75"] 
4

你可以試試這個:

txt = "25 red delicious apples 0.75" 
pattern = Regexp.new('(?<=\d)\s|\s(?=\d)') 
puts txt.split(pattern) 

或IRB:

'25 red delicious apples 0.75'.split(/(?<=\d)\s|\s(?=\d)/) 

與「at」:

'25 red delicious apples at 0.75'.split(/(?<=\d)\s|\sat\s(?=\d)/) 

與循環的例子:

pattern = Regexp.new('(?<=\d)\s|\sat\s(?=\d)') 
File.open('basket.txt').each_line do |line| 
    items = line.split(pattern) 
end 
+1

美麗的表情。 – Bala

+0

呃,我只是不得不編輯這個問題,但我忘了字符串中的'at'。否則,它會工作 –

+0

@Singleton:謝謝<°)))))))> –

0
'25 red delicious apples at 0.75'.scan(/[0-9]+\.?\d*/) #=> ["25", "0.75"] 
+0

這將不匹配單個數字的數字。 – pguardiario

+0

好的。你是對的。將'+'更改爲'*'以匹配單個數字。 – Bala

1

在這種情況下,你應該使用的匹配,而不是split模式。

line = "25 red delicious apples at 0.75\n" 
line.match(/(\d+)\s+(.*)\s+at\s+(\S+)/).values_at(1, 2, 3) 
# => ["25", "red delicious apples", "0.75"] 
0

如何:

'25 red delicious apples at 0.75'.scan /(\d+[.\d]+) (.*) at (\d+[.\d]+)/ 
#=> [["25", "red delicious apples", "0.75"]] 
相關問題