首页 文章

这个正则表达式如何工作?

提问于
浏览
15

this article

/^1?$|^(11+?)\1+$/ 检查一个数字(它在一元中的值)是否为素数 .

使用它, perl -l -e '(1 x $_) !~ /^1?$|^(11+?)\1+$/ && print while ++$_;' 返回素数列表 .

我没有足够的Perl经验,但据我所知,正则表达式将是 true ,对于不是素数的数字 . 因此,如果我们使用此表达式打印所有不产生 true 的数字,我们会有一个素数列表 . 这就是perl查询尝试做的事情 .

关于正则表达式部分,

^1?$ 部分用于计数1为 not prime

^(11+?)\1+$ 用于匹配不是从4开始的素数 .


我不明白的是为什么正则表达式中的 ? 根本需要 . 据我说 /^1$|^(11+)\1+$/ 应该很好,实际上

perl -l -e '(1 x $_) !~ /^1$|^(11+)\1+$/ && print while ++$_;' 给了我同样的素数 .

Is there any flaw in my understanding of the regular expression? Why are the ?s needed?

是不是 ? 应该匹配前面的表达式的零次或一次出现?

2 回答

  • 6

    第一个 ? 用于将空字符串(即0)与非素数匹配 . 如果你没有必要't care whether the regexp matches 0, then it' .

    第二个 ? 仅用于提高效率 . + 通常是"greedy",这意味着它匹配尽可能多的字符,然后如果正则表达式的其余部分无法匹配则回溯 . +? 使其非贪婪,因此它只匹配1个字符,然后如果正则表达式的其余部分无法匹配则尝试匹配更多 . (有关贪婪与非贪婪匹配的更多信息,请参阅the Quantifiers section of perlre . )

    在这个特定的正则表达式中, (11+?) 表示它测试可分性为2( '11' ),然后是3( '111' ),然后是4等 . 如果你使用了 (11+) ,它将用N(数字本身)测试可分性,然后是N-1,那么N-2等等 . 由于除数必须不大于N / 2,没有 ? 会浪费时间测试很多不可能有效的"potential"除数 . 它仍然会匹配非素数,只是更慢 . (另外, $1 将是最大的除数而不是最小的除数 . )

  • 7

    第一个 ? 将使“”(空字符串,一元零)不是素数 . 零被定义为非素数 .

    第二个是不同的;它从贪婪匹配中停止正则表达式 . 它应该大大提高匹配的性能,因为该部分的第一部分( (11+) )赢得了't consume almost the entire string before having to backtrack. If you omit the question mark, you'有效地测试奇数 n 是否可被 n-1 整除,因此一个向下;如果你包括它,你首先测试两个可分性,依此类推 . 显然,数字往往可以被更小的因素整除,所以你的匹配会更快 .

相关问题