我有一个字符串:
"1 chocolate bar at 25"
我希望将此字符串拆分为:
[1, "chocolate bar", 25]
我不知道如何为此分割编写正则表达式。我想知道是否还有其他任何功能可以实现它。
答案 0 :(得分:4)
您可以将scan
与正则表达式一起使用:
"1 chocolate bar at 25".scan(/^(\d+) ([\w ]+) at (\d+)$/).first
如果item_name
有特殊字符,则上述方法无效。
如果您想要更强大的解决方案,可以使用split
:
number1, *words, at, number2 = "1 chocolate bar at 25".split
p [number1, words.join(' '), number2]
# ["1", "chocolate bar", "25"]
number1
是第一部分,number2
是最后一部分,at
是倒数第二部分,而*words
是一个中间包含所有内容的数组。 number2
保证是最后一个字。
这种方法的优点是即使中间有数字," at "
字符串中的某个地方,或者价格是以浮点数形式给出的。
答案 1 :(得分:1)
没有必要使用正则表达式。
str = "1 chocolate bar, 3 donuts and a 7up at 25"
i1 = str.index(' ')
#=> 1
i2 = str.rindex(' at ')
#=> 35
[str[0,i1].to_i, str[i1+1..i2-1], str[i2+3..-1].to_i]
#=> [1, "chocolate bar, 3 donuts and a 7up", 25]
答案 2 :(得分:1)
我愿意:
> s="1 chocolate bar at 25"
> s.scan(/[\d ]+|[[:alpha:] ]+/)
=> ["1 ", "chocolate bar at ", "25"]
然后得到整数和剥离的字符串:
> s.scan(/[\d ]+|[[:alpha:] ]+/).map {|s| Integer(s) rescue s.strip}
=> [1, "chocolate bar at", 25]
并删除" at"
:
> s.scan(/[\d ]+|[[:alpha:] ]+/).map {|s| Integer(s) rescue s[/.*(?=\s+at\s*)/]}
=> [1, "chocolate bar", 25]
答案 3 :(得分:0)
您可以尝试在正则表达式captures
上返回match
方法的(\d+) ([\w ]+) at (\d+)
属性:
string.match(/(\d+) +(\D+) +at +(\d+)/).captures
如果您尚未验证输入字符串是否在所需格式内,则可能有更好的方法来验证和捕获数据。这个解决方案还带来了接受item_name
字段中任何类型字符和最后十进制价格的想法:
string.match(/^(\d+) +(.*) +at +(\d+(?:\.\d+)?)$/).captures
答案 4 :(得分:0)
您也可以这样做:
"1 chocolate bar at 25"
.split()
.reject {|string| string == "at" }
.map {|string| string.scan(/^\D+$/).empty? ? string.to_i : string }
答案 5 :(得分:-1)
我住在价格可能浮动的国家,因此价格更为复杂的匹配。
"1 chocolate bar at 25".
match(/\A(\d+)\s+(.*?)\s+at\s+(\d[.\d]*)\z/).
captures
#⇒ ["1", "chocolate bar", "25"]