How does this regular expression work?

前端 未结 2 1047
情书的邮戳
情书的邮戳 2020-12-05 19:13

From this article,

/^1?$|^(11+?)\\1+$/ checks whether a number(its value in unary) is prime or not.

Using this, perl -l -e \'(1 x $_) !~ /

相关标签:
2条回答
  • 2020-12-05 20:01

    The first ? is for matching the empty string (i.e. 0) as non-prime. If you don't care whether the regexp matches 0, then it's not necessary.

    The second ? is only for efficiency. + is normally "greedy", which means it matches as many characters as are available, and then backtracks if the rest of the regexp fails to match. The +? makes it non-greedy, so it matches only 1 character, and then tries matching more if the rest of the regexp fails to match. (See the Quantifiers section of perlre for more about greedy vs. non-greedy matching.)

    In this particular regexp, the (11+?) means it tests divisibility by 2 ('11'), then 3 ('111'), then 4, etc. If you used (11+), it would test divisibility by N (the number itself), then N-1, then N-2, etc. Since a divisor must be no greater than N/2, without the ? it would waste time testing a lot of "potential" divisors that can't possibly work. It would still match non-prime numbers, just more slowly. (Also, $1 would be the largest divisor instead of the smallest one.)

    0 讨论(0)
  • 2020-12-05 20:06

    The first ? will make "" (the empty string, unary zero) not be a prime number. Zero is defined as not prime.

    The second is different; it stops the regular expression from greedy-matching. It should improve the performance of the match greatly, since the first part of that section ((11+)) won't consume almost the entire string before having to backtrack. If you omit the question mark, you're effectively testing whether odd n is divisible by n-1 and so one down; if you include it, you're testing divisibility by two first and so on upwards. Obviously, numbers tend to be divisible by smaller factors more often, so your match will be faster.

    0 讨论(0)
提交回复
热议问题