regex - 匹配有限自然数级数

标签 regex perl

如何将有限的 natural number 系列与正则表达式匹配?

所以,要求是:

  • 字符串包含数字和空格(作为分隔符)
  • 第一个数字是 1
  • 每个数字(第一个除外)等于前一个数字 + 1

  • 应该匹配 :
  • 1
  • 1 2
  • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  • 从 1 到 10^1000 的一系列后续数字

  • 不应与 匹配:
  • ``
  • 1 3 4
  • 1 2 3 4 5 6 6

  • 除此之外,正则表达式还有一些要求:
  • 它应该是单一的一次性表达式,而不是指令的循环条件算法包
  • 它可以使用 perl 正则表达式的所有功能

  • 我不确定正则表达式是否真的很懒,所以如果它们是的话会很棒。因为自然数列在数论中的本义是非有限的。

    还有最后一个。请注意,我是 而不是 为该工作使用了错误的工具。这根本不是现实世界的编程任务。

    最佳答案

    干得好。在 Perl v5.10 到 v5.14 上测试。关键是 递归模式 ,我们在 (?&Sequence) 规则上递归。这是一种归纳证明。
    bigint 就在那里,以防你真的想从 1 .. 10**10_000 生成一个序列。如果您可以根据您的平台将自己限制为机器 native 整数、32 位或 64 位,它将运行得更快。

    #!/usr/bin/env perl
    use v5.10;
    use bigint;  # only if you need stuff over maxint
    
    my $pat = qr{
        ^
        (?= 1 \b )
        (?<Sequence>
            (?<Number> \d+ )
            (?:
                \s+
                (??{  "(?=" . (1 + $+{Number}) . ")" })
                (?&Sequence)
            )?
        )
        $
    }x;
    
    # first test embedded data
    while (<DATA>) {
        if ( /$pat/ ) {
            print "PASS: ", $_;
    
        } else {
            print "FAIL: ", $_;
        }
    }
    
    # now generate long sequences
    for my $big ( 2, 10, 25, 100, 1000, 10_000, 100_000 ) {
        my $str = q();
        for (my $i = 1; $i <= $big; $i++) {
            $str .= "$i ";
        }
        chop $str;
        if ($str =~ $pat) {
            print "PASS: ";
        } else {
            print "FAIL: ";
        }
        if (length($str) > 60) {
            my $len = length($str);
            my $first = substr($str,   0, 10);
            my $last  = substr($str, -10);
            $str = $first . "[$len chars]" . $last;
        }
        say $str;
    
    }
    
    
    __END__
    5
    fred
    1
    1 2 3
    1 3 2
    1 2 3 4 5
    1 2 3 4 6
    2 3 4 6
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    1 2 3 4 5 6 6
    

    哪个运行产生:
    FAIL: 5
    FAIL: fred
    PASS: 1
    PASS: 1 2 3
    FAIL: 1 3 2
    PASS: 1 2 3 4 5
    FAIL: 1 2 3 4 6
    FAIL: 2 3 4 6
    PASS: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    FAIL: 1 2 3 4 5 6 6
    PASS: 1 2
    PASS: 1 2 3 4 5 6 7 8 9 10
    PASS: 1 2 3 4 5 [65 chars]2 23 24 25
    PASS: 1 2 3 4 5 [291 chars] 98 99 100
    PASS: 1 2 3 4 5 [3892 chars]8 999 1000
    PASS: 1 2 3 4 5 [588894 chars]999 100000
    

    冒着看似自私的风险,a book 涵盖了这类事情。请参阅Programming Perl,4ᵗʰ 版第5 章中的“Fancy Patterns”部分。您需要查看有关“命名组”、“递归模式”和“语法模式”的新部分。这本书在打印机上,应该在一两天内以电子方式提供。

    关于regex - 匹配有限自然数级数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9297080/

    相关文章:

    ruby-on-rails - 如何验证用户名不以特定字符串开头?

    尝试替换大文件中的单词时出现 Perl 错误

    arrays - 如何将数组存储为 Perl 散列中的值?

    perl - 是否有可能欺骗 Perl 使用变量 %INC 并仍然保持全局 %INC 不变?

    perl - 如何在 perl 中制作多线程服务器?

    python - 将括号与 Python 匹配

    javascript - 使用 javascript 和 Jquery 验证 Gmail ID

    python - 用正则表达式抓取带有可选 <spans> 的 <p>

    c# - 删除空字符串

    perl - 当我将 coderef 传递给这个原型(prototype)化的 Perl 子例程时,为什么会出现语法错误?