这是功能:
var isPrime = function(x) {
return (!(/^,?$|^(,,+?)\1+$/.test(Array(++x))));
};
它适用于小数字,但是当数字很大时,会抛出一个异常,表示数组长度无效。我无法理解这里发生了什么。 RegEx测试的作用是什么?为什么这段代码有效?
答案 0 :(得分:9)
Array(++x)
首先生成一串x
逗号。
正则表达式现在:
^,?$ // Match 1 , or none
| // or ...
^(,,+?)\1+$ // A specific number of commas, elaboration below:
逗号的数量至少等于2个逗号,然后重复直到结尾。它试图做的是:
它首先尝试匹配2个逗号(,+?
至少匹配1 ,
懒惰),并使用它来匹配2的所有倍数,除了2本身因为{{的反向引用1}}是强制性的。因为\1
匹配^(,,)\1+$
的偶数,所以2的所有倍数都是。{/ p>
旁注:,
是一个反向引用,它将匹配第一个捕获组匹配的内容,在此初始情况\1
中。因此,在第一阶段,(,,)
将匹配2个逗号。
如果匹配,则表示存在偶数个逗号且该数字不是素数。
如果上面没有匹配,那么它会匹配3个逗号,并使用它来匹配3的所有倍数,再次,除了3本身。所有3的倍数,因为\1
匹配^(,,,)\1+$
的数字,为3的倍数。
旁注:这一次,,
将与\1
匹配,因为现在它位于捕获组中。因此,在第二阶段,(,,,)
将匹配3个逗号。
如果匹配,则表示有多个逗号可以被3整除,因此不是素数。
等等。你可以看到模式吗?
因此,正则表达式实际上会检查从2开始的所有数字,直到\1
的长度等于(,,+?)
返回的数字。当然,对于大数字,您可能会遇到不同类型的错误:
传递给函数的数字对于正则表达式来说太大了,因为正则表达式试图在内存中保留太多东西,因此堆栈会溢出#34; s' s试图找到一个匹配"正如Floris在评论中提到的(这发生在node.js上的下一个错误之前);
由Array(++x)
组成的数组有太多元素,JS不支持。
因此,如果正则表达式匹配,则它不是素数。这也是为什么你在开始时Array(++x)
否定正则表达式测试结果的原因。
答案 1 :(得分:7)
Array(++x).toString()
是一串x
逗号。
这检查它是由以下两者组成的:
,?
:零或一个逗号(,,+?)\1+
:重复多个逗号至少2个因此它检查x
是
0
或1
2
这是什么不是素数的定义。
更详细的解释:
/^A|B$
:从开始到结束的A或B ,?
:逗号,可选(所以,0或1 (,,+?)
:一个或多个逗号,但不是贪心\1+
第一组重复一次或多次请注意,没有什么魔力:它很昂贵,因为它要求引擎测试(,,+?)
的所有可能大小,直到找到它为止。