使用正则表达式比较数字 [英] Using regular expressions to compare numbers
问题描述
所以这是一个明显的你做错了"的例子.我实际上并不打算这样做,但工作中的一次谈话引发了这个问题:
So this is an obvious case of "you're doing it wrong". I don't actually intend on doing this, but a conversation at work spurred this question:
你能生成一个正则表达式来判断一个整数是否小于任意值.
Can you generate a regular expression to determine if an integer is less than an arbitrary value.
对于某些值,这很容易.对于小于 1000 的整数, \d{1,3} 应该可以解决问题.对于整数 <500,这有点棘手,但还不错,因为您可以使用 [0-4]{0,1}\d{1,2}.
For some values this is easy. For integers less than 1000, \d{1,3} should do the trick. For integers < 500, it's a bit trickier, but not that bad, as you can use [0-4]{0,1}\d{1,2}.
一旦你得到任意值,它就会变得很狡猾.例如,所有小于 255 的数字将类似于 \d{1,2} |[0-1]\d{2}|[2][0-4]\d |[2][5][0-4].
Once you get to arbitrary values it gets a lot tricker. For example, all numbers less than 255 would be something like \d{1,2} | [0-1]\d{2}|[2][0-4]\d | [2][5][0-4].
这里有一个正则表达式吗?还是必须以编程方式生成正则表达式?
Is there a single regular expression that works here? Or do you have to programatically generate the regex?
(再次声明,我无意这样做.显然,在您最喜欢的编程语言中使用foo < bar"效率更高且易于阅读.)
(And again, let me point out that I have no intention of actually doing this. Obviously using "foo < bar" in your favorite programming language is far more efficient and easy to read.)
推荐答案
这很容易.
#!/usr/bin/env perl
use strict;
use warnings;
use Regexp::Assemble;
for my $n (@ARGV) {
my $asm = new Regexp::Assemble;
for (1 .. $n) { $asm->add($_) }
for ($asm->re){
s/\)$/\$/;
s/^[^:]*:/^/;
print "$n => /$_/\n";
}
}
现在运行它以查找匹配 1 和该数字之间的整数的模式:
Now run it to find the pattern that matches integers between 1 and that number:
$ perl /tmp/ra 5 15 153 401 1144
5 => /^[12345]$/
15 => /^(?:[23456789]|1[012345]?)$/
153 => /^(?:1(?:[6789]|5[0123]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)$/
401 => /^(?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|3(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|4(?:[123456789]|0[01]?)?|5\d?|6\d?|7\d?|8\d?|9\d?)$/
1144 => /^(?:1(?:0(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|1(?:[56789]|4[01234]?|0\d?|1\d?|2\d?|3\d?)?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|3(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|4(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|5(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|6(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|7(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|8(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|9(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?)$/
这篇关于使用正则表达式比较数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!