我正在尝试匹配字符串中任何地方的400到499之间的数字。例如,两者:
string = "[401] One too three"
string2 = "Yes 450 sir okay"
应该匹配。两者:
string3 = "[123] Test"
string4 = "This is another string"
应该失败。
编写正则表达式的最佳方法是什么?我写道:
string =~ /\d{3}/
查看字符串是否包含三位数的整数。我怎么看是否在范围内?
答案 0 :(得分:6)
如果您实际上不需要数字后缀,而只需确定是或否,则该字符串包含一个介于400-499之间的数字,您可以可以:
所以您最终得到的正则表达式看起来像
regex = /(?:^|\D)4\d{2}(?:\D|$)/
或者,通过使用否定的前瞻/后视:
regex = /(?<!\d)4\d{2}(?!\d)/
,您需要执行上面的步骤1和4才能排除数字,例如1400-1499和4000-4999(以及其他数字超过3的数字,其中埋藏着400-499。然后,您可以在新的红宝石版本中使用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
非常简单的正则表达式,如果您只需要简单的是或否
,则无需提取匹配并将其转换为整数答案 1 :(得分:6)
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"]
答案 2 :(得分:2)
我建议先使用常规的正则表达式从每行中提取数字。然后,使用常规脚本检查范围:
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
我编写的模式实际上应该可以匹配字符串中任意位置的方括号中的任何数字。
答案 3 :(得分:1)
使用正则表达式提取数字,将捕获组转换为整数,并询问Ruby是否在您的范围之内:
Successfully installed sphinx docutils sphinxcontrib-websupport requests packaging typing Jinja2 snowballstemmer alabaster Pygments babel imagesize six urllib3 idna certifi chardet pyparsing MarkupSafe pytz