正则表达式用于匹配字母数字和下划线

803

是否有一个正则表达式可以检查字符串是否仅包含大写和小写字母、数字和下划线?


19
不同的正则表达式引擎对于匹配字母数字字符的方法不一样,这真是令人遗憾。像这样的问题(相当模糊,没有指定任何语言/正则表达式风格)需要一个非常长的,或者至少是一个很有组织的答案来详细讲解每种风格的匹配方法。 - Wiktor Stribiżew
21个回答

1232

要匹配仅包含这些字符(或空字符串)的字符串,请尝试

"^[a-zA-Z0-9_]*$"

这适用于.NET正则表达式,可能也适用于许多其他语言。

分解一下:

^ : start of string
[ : beginning of character group
a-z : any lowercase letter
A-Z : any uppercase letter
0-9 : any digit
_ : underscore
] : end of character group
* : zero or more of the given characters
$ : end of string

如果你不想允许空字符串,可以用+代替*


正如其他人指出的那样,一些正则表达式语言有[a-zA-Z0-9_]的简写形式。在.NET正则表达式语言中,你可以打开ECMAScript行为并使用\w作为快捷方式(得到^\w*$^\w+$)。请注意,在其他语言中,默认情况下在.NET中,\w稍微宽泛,也会匹配其他类型的Unicode字符(感谢Jan指出这一点)。因此,如果你真的打算只匹配仅限于这些字符,使用显式的(较长)形式可能是最好的。


14
如果你曾经去过德国或者看到任何德文文字,你就会明白我在说什么。 - Windows programmer
37
在大多数正则表达式引擎中,\w和[A-Za-z0-9_]并不等价。 \w包括带附加符号的字母、来自其他文字系统的字母等。 - Jan Goyvaerts
5
原问题确实提到了“大写和小写字母”,因此似乎非拉丁文字的“字母”也应该匹配。 - Hakanai
3
只要没有组合字符,[\p{upper}\p{lower}\p{gc=Number}_] 就足够让你正确执行此操作。 - tchrist
5
所有的点赞是怎么回事?这不正确。这只适用于英语。如果你要进行编辑,就编辑它。不要添加“编辑:”,直接将其更正即可。 - doug65536
显示剩余8条评论

462

这里有很多啰嗦的内容,我深感反感,因此我的结论是:

/^\w+$/

\w等同于[A-Za-z0-9_],这基本上是您想要的(除非我们引入Unicode)。

使用+量词,可以匹配一个或多个字符。如果您还想接受空字符串,请改用*


81
\w通常不仅限于ASCII字符。 - tchrist
53
世界上不仅有英语一种语言,因此应该接受这个答案,而不是 [a-z] 及其变体。\w 也会捕获非拉丁字符,例如 šēēāкукареку - Alex from Jitbit
2
在O'Reilly的《精通正则表达式》第318页上进行了验证。 - guidotex
2
在ECMAScript(即在现代Web浏览器中运行的内容)中,\w等同于[a-zA-Z0-9_],这意味着两者都受到ASCII字符集的限制。 - Armen Michaeli
1
如果您正在使用Javascript,您可能需要使用/\p{L}/u(请注意Unicode标志)。演示:"é".match(/\w/) ❌,"é".match(/\p{L}/u) - V. Rubinetti

51

您想检查每个字符是否符合要求,因此我们使用:

[A-Za-z0-9_]

你甚至可以使用简写版本:

\w

这等效于某些正则表达式(请确保在使用之前进行检查)。然后为了表示整个字符串必须匹配,你需要使用:
^

如果要表示字符串必须以该字符开头,则使用

$

为表示字符串必须以该字符结尾,请使用。然后使用。
\w+ or \w*

为了表示“一个或多个”或“零个或多个”,将它们组合起来,我们有:
^\w*$

10
在大多数正则表达式引擎中,\w和[A-Za-z0-9_]并不等价。 \w包含带有变音符号的字母、来自其他文字系统的字母等。 - Jan Goyvaerts
它们与ECMAScript等效。 - Armen Michaeli

49

虽然比\w更冗长,但我个人很欣赏完整的 POSIX 字符类名称的可读性(http://www.zytrax.com/tech/web/regex.htm#special),所以我会说:

^[[:alnum:]_]+$
然而,尽管上述链接的文档说明\w会“匹配在0-9、A-Z和a-z范围内的任何字符(相当于POSIX[:alnum:])”,但我发现这并不正确,至少在使用grep -P时是这样。如果您使用[:alnum:],则需要明确包含下划线,但如果您使用\w,则不需要。以下代码最简洁:

^\w+$

除了易读性外,使用 POSIX 字符类(http://www.regular-expressions.info/posixbrackets.html)意味着您的正则表达式可以在非 ASCII 字符串上工作,而基于范围的正则表达式不会这样做,因为它们依赖于 ASCII 字符的底层排序,这可能与其他字符集不同,并因此排除一些您可能想要捕获的非 ASCII 字符(如 œ 这样的字母)。


43

嗯...问题是:它是否需要至少有一个字符?还是可以是空字符串?

^[A-Za-z0-9_]+$

至少会做一个大写或小写字母、数字或下划线匹配。如果长度可以为零,则将+替换为*

^[A-Za-z0-9_]*$

如果需要包含变音符号(例如cedilla-ç),那么您需要使用单词字符,它与上述内容相同,但包括变音符号字符:
^\w+$

或者

^\w*$

好的,既然你提到了,我也错过了很多其他的法语字符... - BenAlabaster
1
\w 与 [\w] 相同,但输入更少。 - Jan Goyvaerts
是的,你仍然需要使用+或*以及^和$ - \w只检查它是否包含单词字符,而不是仅包含单词字符... - BenAlabaster
奇怪的是,这仍然允许使用美元符号。 - Induster
@Induster,这是因为BenAlabaster刚刚指出的原因。 - Sebas

25
使用
^([A-Za-z]|[0-9]|_)+$

如果您想表达得更明确,可以使用以下方式:

^\w+$

如果您更喜欢简洁的(Perl语法)。


1
处理像葡萄牙语这样的语言时,最好使用^\w+$来匹配带有重音的字母。 - fellyp.santos

22
在计算机科学中,字母数字值通常指的是第一个字符不是数字,而是字母或下划线。之后的字符可以是0-9,A-Z,a-z或下划线(_)。
以下是如何实现这个功能:
在PHP中进行了测试:
$regex = '/^[A-Za-z_][A-Za-z\d_]*$/'

或者拿走
^[A-Za-z_][A-Za-z\d_]*$

将其放置在您的开发语言中。

15

使用先行断言来实现「至少一个」内容。相信我,这样做更容易。

下面是一个示例,要求1-10个字符,包含至少一个数字和一个字母:

^(?=.*\d)(?=.*[A-Za-z])[A-Za-z0-9]{1,10}$

注意: 我本可以使用 \w,但那样会牵涉到 ECMA/Unicode 的考虑,扩大了 \w “单词字符”的覆盖范围。


如果我们想要将下划线和破折号添加到列表中,我们该怎么做? - Rahi

13

这对我有用。我在 O'Reilly 的 "Mastering Regular Expressions" 中发现了这个:

/^\w+$/

说明:

  • ^ 表示匹配字符串的开始位置
    • \w+ 匹配任何单词字符(相当于 [a-zA-Z0-9_])
    • "+" 量词 — 匹配前面的子表达式一次或多次(贪婪模式)
  • $ 表示匹配字符串的结束位置

自行验证:

const regex = /^\w+$/;
const str = `nut_cracker_12`;
let m;

if ((m = regex.exec(str)) !== null) {
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


10

尝试使用我为字符串创建的多语言扩展。

IsAlphaNumeric - 字符串必须至少包含一个 alpha(在 charSet 中指定的 Unicode 范围内的字母)和一个数字(在 numSet 中指定)。此外,该字符串应仅由 alpha 和数字组成。

IsAlpha - 字符串应该至少包含一个 alpha(在指定的语言 charSet 中),并且仅由 alpha 组成。

IsNumeric - 字符串应该至少包含一个数字(在指定的语言 numSet 中),并且仅由数字组成。

所需语言的 charSet/numSet 范围可以指定。Unicode 范围可在 Unicode Chart 上找到。

API:

public static bool IsAlphaNumeric(this string stringToTest)
{
    // English
    const string charSet = "a-zA-Z";
    const string numSet = @"0-9";

    // Greek
    //const string charSet = @"\u0388-\u03EF";
    //const string numSet = @"0-9";

    // Bengali
    //const string charSet = @"\u0985-\u09E3";
    //const string numSet = @"\u09E6-\u09EF";

    // Hindi
    //const string charSet = @"\u0905-\u0963";
    //const string numSet = @"\u0966-\u096F";

    return Regex.Match(stringToTest, @"^(?=[" + numSet + @"]*?[" + charSet + @"]+)(?=[" + charSet + @"]*?[" + numSet + @"]+)[" + charSet + numSet +@"]+$").Success;
}

public static bool IsNumeric(this string stringToTest)
{
    //English
    const string numSet = @"0-9";

    //Hindi
    //const string numSet = @"\u0966-\u096F";

    return Regex.Match(stringToTest, @"^[" + numSet + @"]+$").Success;
}

public static bool IsAlpha(this string stringToTest)
{
    //English
    const string charSet = "a-zA-Z";

    return Regex.Match(stringToTest, @"^[" + charSet + @"]+$").Success;
}

用法:

// English
string test = "AASD121asf";

// Greek
//string test = "Ϡϛβ123";

// Bengali
//string test = "শর৩৮";

// Hindi
//string test = @"क़लम३७ख़";

bool isAlphaNum = test.IsAlphaNumeric();

@Shah:我已经添加了只有字母(和只有数字)的内容。 - Shantanu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接