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

时间:2015-06-09 05:01:51

标签: javascript regex

我有这个正则表达式:

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

我用它来查看字符串中是否至少包含3个字母数字字符。它似乎有效。

它应匹配的字符串示例:

'a3c'
'_0_c_8_'
' 9 9d '

但是,我需要它更快地工作。有没有更好的方法来使用正则表达式匹配相同的模式?

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

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

(不需要修饰符)

3 个答案:

答案 0 :(得分:6)

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

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

See demo

如果你需要一个完整的字符串匹配,你需要附加.*(或.*$如果你想保证你将匹配所有字符串/行的结尾),但是我对regexhero的测试,.*会产生更好的性能):

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

另外,很大程度上取决于引擎。 PCRE具有自动优化功能,包括自动拥有(即它将*转换为*+中的(?:[^a-zA-Z0-9]*+

请在此处查看more details on password validation optimizations

答案 1 :(得分:3)

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

你可以使用它。这比你的快得多,步骤也少。参见demo。你可能也想使用^$锚来确保没有部分匹配。

https://regex101.com/r/nS2lT4/32

原因是

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

                ^^

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

答案 2 :(得分:2)

考虑一下。正则表达式非常强大,因为它们具有表现力且非常灵活(具有前瞻,贪婪消耗和反向跟踪等功能)。几乎总是是一个成本,无论多么轻微。

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

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;
}

现在,关于这个具体情况是否更快,这取决于许多因素,例如语言是否被解释或编译,正则表达式的效率如何等等。

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