Ruby正则表达式匹配数组中的字符串?

时间:2010-10-18 21:27:30

标签: ruby

我对Ruby的正则表达式有点新鲜,(或者我认为一般都是正则表达式),但我想知道是否有一种实用的方法来匹配使用数组的字符串?

让我解释一下,说我在这种情况下有一份成分清单:

1 1/3 cups all-purpose flour
2 teaspoons ground cinnamon
8 ounces shredded mozzarella cheese

最终我需要将成分分成各自的“数量和量度”和“成分名称”,所以就像2 teaspoons ground cinnamon一样,将分为“8 ounces和{{ 1}}。

所以我没有像shredded mozzarella cheese那样拥有一个非常长的正则表达式,而是如何使用数组来保存正则表达式之外的那些值?


更新

我这样做了(感谢cwninja):

(cup\w*|teaspoon\w*ounce\w* ....... )

这让我接近我想要的东西,所以我认为这是我想要的方向。

  # I think the all units should be just singular, then 
  # use ruby function to pluralize them.

units = [
  'tablespoon',
  'teaspoon',
  'cup',
  'can',
  'quart',
  'gallon',
  'pinch',
  'pound',
  'pint',
  'fluid ounce',
  'ounce'
  # ... shortened for brevity
]

joined_units = (units.collect{|u| u.pluralize} + units).join('|')

# There are actually many ingredients, so this is actually an iterator
# but for example sake we are going to just show one.
ingredient = "1 (10 ounce) can diced tomatoes and green chilies, undrained"

ingredient.split(/([\d\/\.\s]+(\([^)]+\))?)\s(#{joined_units})?\s?(.*)/i)

2 个答案:

答案 0 :(得分:26)

就我个人而言,我只是以编程方式构建正则表达式,你可以这样做:

ingredients = [...]
recipe = Regexp(ingredients.join("|"), true) # Case-insensitive

或使用union方法:

recipe = Regexp.union(ingredients)
recipe = /#{regex}/i

...然后使用recipe正则表达式。

只要您保存它并且不继续重新创建它,它应该相当有效。

答案 1 :(得分:3)

对于数组 a ,这样的事情应该有效:

a.each do |line|
    parts = /^([\d\s\.\/]+)\s+(\w+)\s+(.*)$/.match(line)
    # Do something with parts[1 .. 3]
end

例如:

a = [
    '1 1/3 cups all-purpose flour',
    '2 teaspoons ground cinnamon',
    '8 ounces shredded mozzarella cheese',
    '1.5 liters brandy',
]
puts "amount\tunits\tingredient"
a.each do |line|
    parts = /^([\d\s\.\/]+)\s+(\w+)\s+(.*)$/.match(line)
    puts parts[1 .. 3].join("\t")
end