正则表达式挑战

时间:2013-10-16 15:40:05

标签: ruby-on-rails ruby regex ruby-on-rails-3

我试图只抓住一根这个字符串:

Serving Size: 1 cup, halves, Calories: 48.6, Fat: 0.5g, Carbs: 11.7g, Protein: 1g

和许多其他人喜欢它。虽然每个字符串都有不同的变量。例如,上面的字符串可能如下所示:

Serving Size: 100 oz, Calories: 48.6, Fat: 0.5g, Carbs: 11.7g, Protein: 1g

等等......

所以,我现在正试图获得字符串中的“oz”或“cup”部分。

我试过的正则表达式看起来像这样:

(?<=Serving Size:\s\d*\s)

虽然在rubular中它一直说“无效”。

虽然我这样做

(?<=Serving Size:)\s\d*\s

它将完美匹配数字...我正在尝试排除数字并匹配度量类型。

我该怎么做?

3 个答案:

答案 0 :(得分:6)

这个怎么样?

s = "Serving Size: 1 cup, halves, Calories: 48.6, Fat: 0.5g, Carbs: 11.7g, Protein: 1g"

regex = /Serving Size:\s*(?<amount>\d+)\s*(?<units>\w+)/

m = s.match(regex) # => #<MatchData "Serving Size: 1 cup" amount:"1" units:"cup">
m['units'] # => "cup"
m['amount'] # => "1"

答案 1 :(得分:1)

注意:这回答为什么正则表达式无效。 Sergio Tulentsev的回答已经为如何提供了一个很好的解决方案,以获得理想的结果。

如果我正确地解释了您的意图,(?<=Serving Size:\s\d*\s)就是后视,我假设后面是\w+或者与测量单位名称相匹配的东西。您的后视问题(以及(?<=Serving Size:)确实起作用的原因)是,与前瞻不同,后视必须具有定义的长度 - 包括\d*使其无限期。

我的建议是捕获单位,然后从结果中获取所需的信息。像

这样的东西
/Serving Size:\s\d*\s(\w+)/

答案 2 :(得分:1)

/Serving Size: (.+), Calories: (.+), Fat: (.+), Carbs: (.+), Protein: (.+)/

使用捕获组,然后使用$1$2$3等访问它们。