这就是我在做的事情:
c.scan(/[1-9]|1[0-2]/)
由于某种原因,它只返回1到9之间的数字,忽略第二部分。我尝试了一点点,似乎只有在[1-9]部分中排除1时,该方法才会搜索10-12,例如c.scan(/ [2-9] | 1 [0-2] /) 会做。是什么原因?
P.S。我知道这种方法缺乏外观,并且会搜索数字和“数字的一部分”
答案 0 :(得分:3)
更改图案的顺序,并在必要时添加字边界。
c.scan(/\b(?:1[0-2]|[1-9])\b/)
首先使用|
之前的模式。所以在我们的例子中,它匹配从10到12的所有数字。之后是下一个模式,即|
之后使用的模式,现在它匹配所有剩余的数字,范围从1到9.注意这个会匹配9
中的59
。所以我建议你把你的模式放在一个捕获或非捕获组中,并在之前和之后添加单词边界\b
(在单词字符和非单词字符之间匹配)小组。
答案 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"]
与使用单个正则表达式相比,我认为这种方法有几个优点: