在ruby中,如何对1到12的数字使用string.scan(/ regex /)方法?

时间:2014-12-28 23:40:47

标签: ruby regex numbers

这就是我在做的事情:

c.scan(/[1-9]|1[0-2]/)

由于某种原因,它只返回1到9之间的数字,忽略第二部分。我尝试了一点点,似乎只有在[1-9]部分中排除1时,该方法才会搜索10-12,例如c.scan(/ [2-9] | 1 [0-2] /) 会做。是什么原因?

P.S。我知道这种方法缺乏外观,并且会搜索数字和“数字的一部分”

3 个答案:

答案 0 :(得分:3)

更改图案的顺序,并在必要时添加字边界。

c.scan(/\b(?:1[0-2]|[1-9])\b/)

首先使用|之前的模式。所以在我们的例子中,它匹配从10到12的所有数字。之后是下一个模式,即|之后使用的模式,现在它匹配所有剩余的数字,范围从1到9.注意这个会匹配9中的59。所以我建议你把你的模式放在一个捕获或非捕获组中,并在之前和之后添加单词边界\b在单词字符和非单词字符之间匹配)小组。

DEMO

答案 1 :(得分:0)

|从左到右匹配,右侧的第一部分(1)始终与左侧匹配。扭转它们:

c.scan(/1[0-2]|[1-9]/)

答案 2 :(得分:0)

这是你可以考虑提取1到12之间的数字的另一种方式(假设这是你想要做的):

c = '14 0 11x 15 003 y12'
c.scan(/\d+/).map(&:to_i).select { |n| (1..12).cover?(n) }
  #=> [11, 3, 12]

我已经返回了一个整数数组,而不是字符串,认为可能更有用,但如果你想要字符串:

c.scan(/\d+/).map { |s| s.to_i.to_s }
 .select { |s| ['10', '11', '12', *'1'..'9'].include?(s) }
  #=> ["11", "3", "12"]

与使用单个正则表达式相比,我认为这种方法有几个优点:

  • 很容易理解;
  • 正则表达式很简单;
  • 如果允许的值发生变化,则很容易修改;和
  • 它可分为三部分以方便测试。