字符类
是专门命名的中括号序列;除了字符类,还有等价类、排序类,但基本用不上,只用字符类。
[:alpha:]:匹配字母,等价于[a-zA-Z]
[:digit:]:匹配数字,等价于[0-9]
[:xdigit:]:匹配十六进制数,等价于[0-9a-fA-F]
这个东西为什么叫字符类
正则表达式中的 字符类 这个术语确实值得深入探讨其命名原因。为什么把 [a-z]、[aeiou] 或者 [:alpha:] 这些东西叫做“类”呢?这主要源于其本质和功能:
核心含义是“分类”或“集合”:
“类”在这里的含义更接近于 “类别” 或 “分类”,而不是面向对象编程中的“类”。
它的核心思想是:将具有某种共同特征的字符划分到同一个组里。这个组就代表了一“类”字符。
[a-z] 代表的是“所有小写字母”这个类别的字符。
[aeiou] 代表的是“所有元音字母”这个类别的字符。
[:digit:] 代表的是“所有数字字符”这个类别的字符。
[0-9a-fA-F] 代表的是“所有十六进制数字字符”这个类别的字符。
数学集合论的体现:
在数学(集合论)中,我们把具有特定性质的对象归类在一起,称为一个集合。
正则表达式的字符类 [...] 本质上定义了一个字符的集合。匹配字符类,就是匹配属于这个集合中的任意一个字符。
因此,“字符类”可以理解为“字符集合类”的简称,指代的是某一类字符构成的集合。
与“等价类”、“排序类”的命名一致性:
你提到的 [:alpha:]、[:digit:] 是 POSIX 字符类,它们是预定义的、具有特定名称的字符集合。
同样属于 POSIX 标准的还有:
等价类: 表示在特定语言环境下被视为等价的字符序列(如 [[=n=]] 可能匹配 ñ 或 ñ)。它定义的是“被视为等价”的一类字符序列。
排序类: 表示在特定语言环境下属于同一排序单位的字符序列(如某些语言中的 ch 被视为一个单位)。它定义的是“排序规则相同”的一类字符序列。
虽然等价类和排序类在日常编程中用得极少(主要涉及复杂的本地化/排序规则),但它们和字符类共享了“类”这个概念,因为它们都是在某种规则下对字符进行的分类(等价分类、排序分类)。
“类”强调了抽象和归类:
使用“类”这个词,而不是简单地叫“字符集合”,突出了正则表达式的一个重要功能:对字符进行抽象和归类。
它允许你忽略具体的字符值,转而关注字符的属性或所属的组别。比如:
你想匹配一个字母,不必穷举 a|b|c|...|z|A|B|...|Z,直接用 [:alpha:] 表示“字母类”即可。
你想匹配一个数字,用 [:digit:] 表示“数字类”即可。
这种基于类别的匹配,使得正则表达式更简洁、更易读(一旦理解类名含义)、更具可移植性(尤其对于像 [:alpha:] 这种能适应不同语言环境的类)。
总结来说,“字符类”中的“类”字,其核心含义是“类别”或“分类”。它指代的是:
一个由方括号 [...] 定义的字符集合。
这个集合包含了具有某种共同特征(如:是小写字母、是数字、是元音、是十六进制字符等)的一类字符。
它是一种对字符进行抽象归类的方法,方便基于属性而非具体值进行匹配。
所以,当你看到 [a-z]、[0-9] 或 [:alpha:] 时,把它们理解成 “小写字母类”、“数字字符类”、“字母字符类” 就非常贴切了。这个名字准确地反映了它们的功能本质:定义一个字符的类别。
需要注意的是,通常字符类在真正使用过程中,会再加上一个中括号,例如[[:alpha:]]。之所以如此,是因为这些字符类只是一种命名好的字符集合。例如[:lower:]对应的字符集合是a-z,而不是[a-z],所以要想让其表示这些命名字符类中的任一字符,需要再加上一层括号[[:lower:]],它才等价于[a-z]。可能会更有助于理解使用字符类的时候为什么要加两个中括号的例子是[[1]],它表示不包含任何小写字母
:lower: ↩︎