【问题标题】:Using regular expressions to compare numbers使用正则表达式比较数字
【发布时间】:2013-01-17 00:02:10
【问题描述】:

所以这是一个明显的“你做错了”的例子。我实际上并不打算这样做,但工作中的一次谈话引发了这个问题:

你能否生成一个正则表达式来确定一个整数是否小于任意值。

对于某些值,这很容易。对于小于 1000 的整数,\d{1,3} 应该可以解决问题。对于小于 500 的整数,它有点棘手,但还不错,因为您可以使用 [0-4]{0,1}\d{1,2}。

一旦你得到任意值,它就会变得很棘手。例如,所有小于 255 的数字都类似于 \d{1,2} | [0-1]\d{2}|[2][0-4]\d| [2][5][0-4]。

是否有一个正则表达式可以在这里工作?还是您必须以编程方式生成正则表达式?

(我再次指出,我并没有实际这样做的意图。显然,在您最喜欢的编程语言中使用“foo

【问题讨论】:

  • 如果这就是您的意思,您可以将必须​​的三个表达式组合成一个表达式。

标签: regex


【解决方案1】:

这很容易。

#!/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 和该数字之间的整数的模式:

$ 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?)?)$/

【讨论】:

    【解决方案2】:

    您将需要为每个边界数生成表达式。假设有一个正则表达式可以完成这项工作。然后,该正则表达式必须能够将某些字符序列作为输入。但是,我们知道正则表达式和有限状态自动机是等价的,所以这就像说我们可以构造一个 FSM,因为可能的数量是无限的,这将需要无限数量的状态,这与 FSA 的定义相矛盾。

    【讨论】:

    • 嗯?你是说它做不到,还是说这是一种非常有趣的说法?即使 OP 明确暗示非负数空间,您是否在暗示负数?
    • 无法完成。通常,您不能编写一个正则表达式来告诉您任意数字是否大于任意界限,因为它们不是有限的。
    • 如果 OP 只是一个特定的数字,他可以很简单地做到这一点——枚举所有低于他的界限的值。然后,如果他感到雄心勃勃,请最小化相应的 FSM 并使用最小的正则表达式。
    • @tripleee:“任意长度,但有限”仅在语义上是矛盾的,不需要自动机知识。让我想起了 Verizon 的数据计划。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多