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

字符类减法

XML SchemaXPath.NET(2.0 版及更高版本)和 JGsoft 正则表达式风格支持字符类减法。它可以轻松匹配出现在一个列表(字符类)中的任何单个字符,但不出现在另一个列表(减去类)中。其语法为 [class-[subtract]]。如果连字符后面的字符是左括号,这些风格会将连字符解释为减法运算符,而不是范围运算符。你可以在减去的字符类中使用完整的字符类语法。

字符类 [a-z-[aeiuo]] 匹配不是元音的单个字母。换句话说:它匹配单个辅音。如果没有字符类减法或 交集,执行此操作的唯一方法是列出所有辅音:[b-df-hj-np-tv-z]

字符类 [\p{Nd}-[^\p{IsThai}]] 匹配任意单个泰语数字。基本类匹配任何 Unicode 数字。从该类中减去所有非泰语字符。[\p{Nd}-[\P{IsThai}]] 执行相同操作。[\p{IsThai}-[^\p{Nd}]][\p{IsThai}-[\P{Nd}]] 也通过从泰语字符中减去所有非数字来匹配单个泰语数字。

嵌套字符类减法

由于你可以在被减字符类中使用完整的字符类语法,因此可以从被减类中减去一个类。[0-9-[0-6-[0-3]]] 首先从 0-6 中减去 0-3,得到 [0-9-[4-6]][0-37-9],它匹配字符串 0123789 中的任何字符。

类减法必须始终是字符类中的最后一个元素。[0-9-[4-6]a-f] 不是有效的正则表达式。它应重写为 [0-9a-f-[4-6]]。减法对整个类起作用。例如,[\p{Ll}\p{Lu}-[\p{IsBasicLatin}]] 匹配所有大写和小写 Unicode 字母,但任何 ASCII 字母除外。\p{IsBasicLatin} 从 \p{Ll}\p{Lu} 的组合中减去,而不是单独从 \p{Lu} 中减去。此正则表达式将不匹配 abc

虽然可以使用嵌套字符类减法,但不能连续减去两个类。要从包含所有 Unicode 字母的类中减去 ASCII 字符和希腊字符,请将 ASCII 和希腊字符组合到一个类中,并减去该类,如 [\p{L}-[\p{IsBasicLatin}\p{IsGreek}]]

否定优先于减法

字符类 [^1234-[3456]] 既被否定又被减去。在所有支持字符类减法的风格中,基本类在被减去之前会被否定。此类应解读为:“(非 1234)减去 3456”。因此,此字符类匹配除数字 1、2、3、4、5 和 6 之外的任何字符。

与其他正则表达风格的符号兼容性

请注意,像 [a-z-[aeiuo]] 这样的正则表达式在大多数不支持字符类减法的正则表达式风格中不会引发任何错误。但它也不会匹配你想要的内容。在大多数风格中,此正则表达式由一个字符类后跟一个文字 ] 组成。字符类匹配一个字符,该字符要么在 a-z 范围内,要么是连字符,要么是左括号,要么是元音。由于 a-z 范围和元音是冗余的,因此可以使用 [a-z-[][-[a-z] 在 Perl 中编写此字符类。范围后的连字符被视为一个文字字符,就像左括号后紧跟的连字符一样。在 XML、.NET 和 JGsoft 风格中也是如此。 [a-z-_] 在这些风格中匹配小写字母、连字符或下划线。

严格来说,这意味着字符类减法语法与 Perl 和大多数其他正则表达式风格不兼容。但在实践中没有区别。在字符类范围内使用非字母数字字符是一种非常不好的做法,因为它依赖于 ASCII 字符表中字符的顺序。这使得继承你工作的程序员难以理解正则表达式。虽然 [A-[] 在 Perl 中匹配任何大写字母或左方括号,但将此正则表达式写成 [A-Z[] 会更清晰。前一个正则表达式将导致 XML、.NET 和 JGsoft 风格出现错误,因为它们将 -[] 解释为空减去的类,留下一个不平衡的 [