/^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 回答
第一个
?
用于将空字符串(即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
将是最大的除数而不是最小的除数 . )第一个
?
将使“”(空字符串,一元零)不是素数 . 零被定义为非素数 .第二个是不同的;它从贪婪匹配中停止正则表达式 . 它应该大大提高匹配的性能,因为该部分的第一部分(
(11+)
)赢得了't consume almost the entire string before having to backtrack. If you omit the question mark, you'有效地测试奇数n
是否可被n-1
整除,因此一个向下;如果你包括它,你首先测试两个可分性,依此类推 . 显然,数字往往可以被更小的因素整除,所以你的匹配会更快 .