2

我需要一些建议来完善正则表达式。我试图用一个表达式将一个字符串分成三部分。行来自格式如下的文本文件:

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)。我还想摆脱浮动末尾的换行符。

4

6 回答 6

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)/)

与“在”:

'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
于 2013-10-24T07:59:14.253 回答
2

我会使用 match 而不是 split 来完成这个任务。这样,您将能够更准确地获取组。例如,如果我们假设产品名称中没有数字:

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"
于 2013-10-24T07:51:25.640 回答
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"]
于 2013-10-24T09:10:08.733 回答
0
p "25 red delicious apples 0.75".partition(/[\D\s]+/)
#=> ["25", " red delicious apples ", "0.75"]
于 2013-10-24T07:54:51.473 回答
0
'25 red delicious apples at 0.75'.scan(/[0-9]+\.?\d*/) #=> ["25", "0.75"]
于 2013-10-24T09:07:21.733 回答
0

怎么样:

'25 red delicious apples at 0.75'.scan /(\d+[.\d]+) (.*) at (\d+[.\d]+)/
#=> [["25", "red delicious apples", "0.75"]]
于 2013-10-24T11:01:42.753 回答