快速入门
教程
工具和语言
示例
参考
书评
正则表达式教程
简介
目录
特殊字符
不可打印字符
正则表达式引擎内部
字符类
字符类减法
字符类交集
简写字符类
词边界
交替
可选项
重复
分组和捕获
反向引用
反向引用,第 2 部分
命名组
相对反向引用
分支重置组
自由间距和注释
Unicode
模式修饰符
原子分组
占有量词
前瞻和后顾
环视,第 2 部分
将文本排除在匹配之外
条件
平衡组
递归
子例程
无限递归
递归和量词
递归和捕获
递归和反向引用
递归和回溯
POSIX 方括号表达式
零长度匹配
继续匹配
本网站上的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式示例
正则表达式参考
替换字符串参考
书评
可打印 PDF
关于本网站
RSS 源和博客
RegexBuddy—Better than a regular expression tutorial!

字符类或字符集

使用“字符类”(也称为“字符集”),你可以告诉正则表达式引擎仅匹配多个字符中的一个。只需将你想要匹配的字符放在方括号中。如果你想要匹配 a 或 e,请使用 [ae]。你可以在 gr[ae]y 中使用它来匹配 graygrey。如果你不知道你要搜索的文档是用美式英语还是英式英语编写的,这将非常有用。

字符类仅匹配单个字符。 gr[ae]y 不匹配 graaygraey 或任何类似内容。字符类中字符的顺序无关紧要。结果是相同的。

您可以在字符类别中使用连字符来指定字符范围。 [0-9] 匹配 0 到 9 之间的单个数字。您可以使用多个范围。 [0-9a-fA-F] 匹配单个十六进制数字,不区分大小写。您可以组合范围和单个字符。 [0-9a-fxA-FX] 匹配十六进制数字或字母 X。同样,字符和范围的顺序无关紧要。

字符类别是正则表达式中最常用的功能之一。您可以找到单词,即使它拼写错误,例如 sep[ae]r[ae]teli[cs]en[cs]e。您可以使用 [A-Za-z_][A-Za-z_0-9]* 在编程语言中找到标识符。您可以使用 0[xX][A-Fa-f0-9]+ 找到 C 样式的十六进制数字。

否定字符类别

在开方括号后键入脱字符号会否定字符类别。结果是字符类别匹配不在字符类别中的任何字符。与不同,否定字符类别也匹配(不可见的)换行符。如果您不希望否定字符类别匹配换行符,则需要在类别中包含换行符。 [^0-9\r\n] 匹配任何不是数字或换行符的字符。

记住,取反的字符类仍然必须匹配一个字符很重要。 q[^u] 意味着:“一个 q 后面不跟 u”。它意味着:“一个 q 后面跟一个不是 u 的字符”。它不匹配字符串 Iraq 中的 q。它匹配字符串 Iraq is a country 中的 q 和 q 后面的空格。事实上:空格成为整体匹配的一部分,因为它是上面正则表达式中取反的字符类匹配的“不是 u 的字符”。如果你希望正则表达式匹配两个字符串中的 q,并且只匹配 q,你需要使用 否定前瞻q(?!u)。但我们稍后会讲到这一点。

字符类中的元字符

在大多数正则表达式风格中,字符类中的唯一特殊字符或元字符是闭合方括号 ]、反斜杠 \、插入符号 ^ 和连字符 -通常的元字符 是字符类中的普通字符,不需要用反斜杠转义。要搜索星号或加号,请使用 [+*]。如果你转义字符类中的常规元字符,你的正则表达式将正常工作,但这样做会显著降低可读性。

要在字符类中包含一个没有任何特殊含义的反斜杠作为字符,你必须用另一个反斜杠转义它。 [\\x] 匹配一个反斜杠或一个 x。闭合方括号 ]、插入符号 ^ 和连字符 - 可以通过用反斜杠转义它们或将它们放在不具有特殊含义的位置来包含。 POSIXGNU 风格是个例外。它们将字符类中的反斜杠视为文字字符。因此,使用这些风格,你无法转义字符类中的任何内容。

要将未转义的插入符号作为文字包含,请将其放在除开括号右后方以外的任何位置。 [x^] 匹配一个 x 或一个插入符号。这适用于本教程中讨论的所有风格。

您可以通过将转义后的闭合方括号放在开合方括号后面或否定脱字符号后面来包含它。 []x] 匹配闭合方括号或 x。 [^]x] 匹配任何不是闭合方括号或 x 的字符。这在 JavaScript 中不起作用,它将 [] 视为始终无法匹配的空字符类,并将 [^] 视为匹配任何单个字符的否定空字符类。 Ruby 将空字符类视为错误。因此,JavaScript 和 Ruby 都需要使用反斜杠转义闭合方括号,才能将它们作为字符类中的字面量包含在内。

连字符可以包含在开合方括号后面,或闭合方括号前面,或否定脱字符号后面。 [-x][x-] 都匹配 x 或连字符。 [^-x][^x-] 匹配任何不是 x 或连字符的字符。这适用于本教程中讨论的所有风格。字符类中无法形成范围的其他位置的连字符可能会被解释为字面量或错误。正则表达式风格对此非常不一致。

许多在字符类外部使用的正则表达式标记也可以在字符类内部使用。这包括 不可打印字符 的字符转义、八进制转义和十六进制转义。对于支持 Unicode 的风格,它还包括 Unicode 字符转义和 Unicode 属性。 [$\u20AC] 匹配美元或欧元符号,假设您的正则表达式风格支持 Unicode 转义。

重复字符类别

如果你使用 ?*+ 运算符重复一个字符类别,你重复的是整个字符类别。你不会只重复它匹配的字符。正则表达式 [0-9]+ 可以匹配 837222

如果你想重复匹配的字符,而不是类别,你需要使用反向引用。([0-9])\1+ 匹配 222 但不匹配 837。当应用于字符串 833337 时,它匹配该字符串中间的 3333。如果你不想要这样,你需要使用 环视

查看正则表达式引擎内部

正如前面提到的:字符类别中字符的顺序无关紧要。gr[ae]yIs his hair grey or gray? 中匹配 grey,因为那是最左匹配。我们已经看到了 引擎如何应用仅由文本字符组成的正则表达式。现在,我们将看到它如何应用具有多个排列的正则表达式。也就是说:gr[ae]y 可以匹配 graygrey

字符串中的前十二个字符没有发生值得注意的事情。引擎在每一步都无法匹配 g,并继续匹配字符串中的下一个字符。当引擎到达第 13 个字符时,g 被匹配。然后,引擎尝试用文本匹配正则表达式的其余部分。正则表达式中的下一个标记是文本字符 r,它匹配文本中的下一个字符。因此,第三个标记 [ae] 在文本中的下一个字符(e)处尝试。字符类别给引擎两个选项:匹配 a 或匹配 e。它首先尝试匹配 a,但失败了。

但由于我们使用的是正则表达式导向引擎,因此它必须继续尝试匹配正则表达式模式的所有其他排列,然后再决定无法将正则表达式与从第 13 个字符开始的文本进行匹配。因此,它继续使用其他选项,并发现 e 匹配 e。最后一个正则表达式标记是 y,它也可以与以下字符匹配。引擎已找到与从第 13 个字符开始的文本完全匹配的内容。它将 grey 作为匹配结果返回,并且不再进一步查找。同样,即使我们将 a 放在字符类中,并且可以在字符串中匹配 gray,但返回的仍然是最左边的匹配。但是,引擎根本没有进行到这一步,因为它在它的左边找到了另一个同样有效的匹配。仅当您告诉正则表达式引擎在主题字符串的第一个匹配之后继续查找第二个匹配时,才会匹配 gray