Regex模式查看字符串是否包含范围内的数字



我试图在字符串中的任何位置匹配一个介于400和499之间的数字。例如,两者:

string = "[401] One too three"
string2 = "Yes 450 sir okay"

应该匹配。两者:

string3 = "[123] Test"
string4 = "This is another string"

应该失败。

编写正则表达式的最佳方式是什么?我写道:

string =~ /d{3}/

查看字符串是否包含三位整数。我如何才能看到这是否在范围内?

如果你实际上不需要数字后缀,只需要确定yesno字符串包含400-499范围内的数字,你可以:

  1. 检查您是否在一行的开头,或者后面有一个非数字字符
  2. 数字"4"后跟
  3. 后面跟着的任意2位数字
  4. 行尾或非数字字符

所以您最终会得到一个类似的正则表达式

regex = /(?:^|D)4d{2}(?:D|$)/

或者,通过使用消极的前瞻性/前瞻性:

regex = /(?<!d)4d{2}(?!d)/

您需要上面的第1步和第4步来排除1400-1499和4000-4999等数字(以及其他包含400-499的超过3位数字的数字(。然后,您可以在较新的ruby版本中使用String#match?来获得一个简单的布尔值:

string.match?(regex)   # => true
string2.match?(regex)  # => true
string3.match?(regex)  # => false
string4.match?(regex)  # => false
"1400".match?(regex)   # => false
"400".match?(regex)    # => true
"4000".match?(regex)   # => false
"[1400]".match?(regex) # => false
"[400]".match?(regex)  # => true
"[4000]".match?(regex) # => false

相当简单的正则表达式,如果您只需要一个简单的yesno,则无需提取匹配项并将其转换为整数

def doit(str, rng)
str.gsub(/-?d+/).find { |s| rng.cover?(s.to_i) }
end
doit "[401] One too three", 400..499     #=> "401"
doit "Yes 450 sir okay", 400..499        #=> "450"
doit "Yes -450 sir okay", -499..400      #=> "-450"
doit "[123] Test", 400..499              #=> nil
doit "This is another string", 400..499  #=> nil

回想一下,当与单个参数一起使用时,String#gsub返回一个枚举器,而没有块。枚举器只生成匹配项,不执行替换。我发现了很多情况,比如这里,这种形式的方法可以发挥优势。

如果str可能包含指定范围内多个整数的表示,并且所有这些都是所需的,则只需将Enumerable#find替换为Enumerable#select:

"401, 532 and -126".gsub(/-?d+/).select { |s| (-127..451).cover?(s.to_i) }
#=> ["401", "-126"]

我建议使用通用正则表达式首先从每行中提取数字。然后,使用常规脚本检查范围:

s = "[404] Yes sir okay"
data = s.match(/[(d+)]/)
data.captures
num = data[1].to_i
if (num >= 400 && num < 500)
print "Match"
else
print "No Match"
end

演示

我编写的模式实际上应该能够匹配括号中的任何数字,字符串中的任何位置。

用正则表达式提取数字,将捕获组转换为整数,并询问Ruby它们是否在您的边界之间:

s = "[499] One too three"
lo = 400
hi = 499
puts s =~ /(d{3})/ && $1.to_i.between?(lo, hi)

最新更新