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

Most efficient regex for checking if a string contains at least 3 alphanumeric characters

本文关键字:数字字符 正则表达式 有效 3个 字符串 检查 是否 包含 用于      更新时间:2023-09-26

我有这个正则表达式:

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

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

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

'a3c'
'_0_c_8_'
' 9 9d '

然而,我需要它工作得更快。有没有更好的方法可以使用regex来匹配相同的模式?


编辑:我最终使用了这个正则表达式:

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

(不需要修改器(

最有效的regex方法是使用对比度原则,即并排使用相反的字符类。这里有一个正则表达式,可以用来检查字符串是否有3个拉丁字母或数字:

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

请参阅演示。

如果你需要一个完整的字符串匹配,你需要附加.*(或者.*$,如果你想保证你会匹配到字符串/行的末尾(,但在我对regexhero的测试中,.*产生了更好的性能(:

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

此外,这在很大程度上取决于发动机。PCRE具有包含自动占有的自动优化(即,它在(?:[^a-zA-Z0-9]*+中将*变成*+(。

请在此处查看有关密码验证优化的更多详细信息。

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

你可以用这个。这比你的要快得多,所需的步骤也要少得多。请参阅演示。您可能也想使用^$锚点来确保没有部分匹配。

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

原因是

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

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

考虑一下。正则表达式之所以强大,是因为它们表现力强且非常灵活(具有前瞻性、贪婪消耗和回溯等功能(。几乎总会有的成本,无论多么小。

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

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

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

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