Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用于检查字符串是否包含至少3个字母数字字符的最有效的正则表达式_Javascript_Regex - Fatal编程技术网

Javascript 用于检查字符串是否包含至少3个字母数字字符的最有效的正则表达式

Javascript 用于检查字符串是否包含至少3个字母数字字符的最有效的正则表达式,javascript,regex,Javascript,Regex,我有一个正则表达式: (?:.*[a-zA-Z0-9].*){3} 我使用它来查看字符串中是否至少包含3个字母数字字符。它似乎起作用了 它应该匹配的字符串示例: 'a3c' '_0_c_8_' ' 9 9d ' 但是,我需要它工作得更快。有没有更好的方法使用正则表达式来匹配相同的模式 编辑: 我最终将此用于我的目的: (?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3} (不需要修改器) 您可以使用它。这比您的要快得多,并且所需的步骤要少得多。请参阅演示。您可能还希望使用^$锚

我有一个正则表达式:

(?:.*[a-zA-Z0-9].*){3}
我使用它来查看字符串中是否至少包含3个字母数字字符。它似乎起作用了

它应该匹配的字符串示例:

'a3c'
'_0_c_8_'
' 9 9d '
但是,我需要它工作得更快。有没有更好的方法使用正则表达式来匹配相同的模式


编辑: 我最终将此用于我的目的:

(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}
(不需要修改器)

您可以使用它。这比您的要快得多,并且所需的步骤要少得多。请参阅演示。您可能还希望使用
^$
锚定,以确保没有部分匹配

原因是

(?:.*[a-zA-Z0-9].*){3}

                ^^

<>这实际上消耗了整个字符串,然后引擎必须回溯。当使用另一个正则表达式时,避免了

。正则表达式之所以强大,是因为它们具有很强的表达能力和灵活性(具有前瞻性、贪婪消费和回溯跟踪等特性)。这几乎总是要付出代价的,不管代价有多小

如果您想要原始速度(并且愿意放弃表达能力),您可能会发现完全绕过正则表达式,只计算字符串会更快,例如使用以下伪代码:

def hasThreeAlphaNums(str):
    alphanums = 0
    for pos = 0 to len(str) - 1:
        if str[pos] in set "[a-zA-Z0-9]":
            alphanums++
            if alphanums == 3:
                return true
    return false
它是一个解析器(在本例中是一个非常简单的解析器),一个比正则表达式更强大的工具。对于一个更具体的例子,考虑下面的C代码:

#include <ctype.h>
int hasThreeAlphaNums (char *str) {
    int count = 0;
    for (int ch = *str; ch != '\0'; str++)
        if (isalnum (ch))
            if (++count == 3)
                return 1;
    return 0;
}
#包括
int有三个字母(char*str){
整数计数=0;
对于(int ch=*str;ch!='\0';str++)
if(isalnum(ch))
如果(++计数==3)
返回1;
返回0;
}
现在,对于这个特定的情况,这是否更快,取决于许多因素,比如语言是否被解释或编译,正则表达式在幕后的效率如何,等等


这就是为什么优化的口号是“测量,不要猜测!”您应该评估目标环境中的可能性。

最有效的正则表达式方法是使用,即并排使用相反的字符类。下面是一个正则表达式,可用于检查字符串是否有3个拉丁字母或数字:

^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}

如果您需要完整的字符串匹配,则需要追加
*
(或者
*$
,如果您想保证将匹配所有字符串/行的末尾),但是在我对regexhero的测试中,
*
会产生更好的性能):

而且,这在很大程度上取决于发动机。PCRE具有自动优化功能,包括自动占有(即,它将
*
转换为
*+
中的
*+
(?:[^a-zA-Z0-9]*+)


请参见此处。

如果也可以匹配下划线,则将字符集替换为\w也会稍微提高性能performance@RodrigoLópez我不太确定OP是否希望:(你对什么样的正则表达式感兴趣?@Stribizev我对ECMAScript正则表达式感兴趣正则表达式可以被锚定,并且
*
被删除。我检查了几件事,结果发现
(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}.
慢得多((:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}/code>(~17%)。我编辑了答案。我相信字符串锚的开始在这里非常有用,我在Regexero上针对提供的输入进行了测试,
(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}.
模式每秒产生422318次迭代,
(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}
(没有
)产生341375次IP,
^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}
产生了…1371000个IP:)如果不进行测试,很容易看出
*
将相等或较慢(通常较慢,因为引擎需要检查字符串的其余部分是否有新行字符,尽管它可以在
s
模式下跳过).The
^
将强制仅在字符串开头执行匹配,因此,当索引0中没有匹配项时,它当然会避免从后续索引中搜索。我没有选择此作为答案,因为它没有回答我的问题。但是,我认为这是一个很好的建议,所以谢谢和+1。@user3772517,没关系,就是这样有时,在问题限制之外寻找其他解决方案是很好的,因为提问者并不总是正确的。但是,如果你需要正则表达式,那么你就需要正则表达式,这是无法回避的:-)
^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}
^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}.*