正则笔记之字符组

普通字符组

字符组是一组字符,在正则表达式中,它表示同一位置可能出现的各种字符。

字符组的写法

在一对方括号   [    ]   之间列出所有可能的字符。   例如:   [314]    [ab]  [#;]   等。

正则表达式提供了 - 范围表示法。形如:   [x-y]   (x 的码值要小于 y 的码值)表示从 x 到 y 整个范围内的字符。
  例如:
 
[0-9]

表示 0 到 9 之间的数字。

码值对照表

码值 字符 码值 字符 码值 字符
48 0 63 ? 78 N
49 1 64 @ 79 O
50 2 65 A 80 p
51 3 66 B 81 Q
52 4 67 C 82 R
53 5 68 D 83 S
54 6 69 E 84 T
55 7 70 F 85 U
56 8 71 G 86 V
57 9 72 H 87 W
58 : 73 I 88 X
59 ; 74 J 89 Y
60 < 75 K 90 Z
61 = 76 L 91 [
62 > 77 M 92 \
码值 字符 码值 字符
93 ] 108 l
94 ^ 109 m
95 110 n
96 ` 111 o
97 a 112 p
98 b 113 q
99 c 114 r
100 d 115 s
101 e 116 t
102 f 117 u
103 g 118 v
104 h 119 w
105 i 120 x
106 j 121 y
107 k 122 z

例子:匹配数字、大小写字母

正则表达式 ^[o-z]$   当匹配到字符时也成立,比如字符   :   的码值是 58, 刚好在此正则表达式的匹配范围内;

所以此处的正确写法应该是要并列多个 - 范围表达式, 使用   [0-9A-Za-z]   可以匹配数字、大小写字母。

说明: ^   和 $ 是正则表达式中的特殊字符,分别表示”定位到字符串的起始位置”和”定位到字符串的结束位置”。

元字符和转义

字符组中的横线 -   不能匹配横线字符, 而是用来表示范围,类似的字符在正则表达式中称为元字符。

转义写法

正则表达式中,取消特殊含义的做法都是转义。

  1. 在元字符前加上反斜线 \   表示转义。

  2. 如果 -   紧跟在开方括号   [   后面,那么   -   此时表示普通字符。

  3. 在开闭括号一起使用时,只有开方括号   [   需要转义, 闭方括号   ]   不需要转义。   比如:   \[012]  

# Python 语言
# 作为普通字符串
re.search("^[-09]$", "3") != None  # false
re.search("^[-09]$", "-") != None  # true

# 作为元字符
re.search("^[0-9]$", "3") != None  # true
re.search("^[0-9]$", "-") != None  # false

# 转义后作为普通字符
re.search("^[0\\-9]$", "3") != None  # false
re.search("^[0\\-9]$", "-") != None  # true

正则表达式中的每个反斜线字符 \   在字符串(正则表达式之外)还必须转义为   \\   。不过有些语言也提供原生字符串,比如 Python 的原生字符串形式是   r"string"   ,但是不是所有的语言都支持原生字符串,比如:Java 。

# Python 语言
# 原生字符串的使用
re.search(r"^[0\-9]$", "3") != None # false

排除型字符组

在当前位置,匹配一个没有列出的字符,称为排除型字符组。 写作   [^...]  

注意:

  1. 排除型字符组必须匹配一个字符。

  2. 在排除型字符组中如果要表示普通字符 -   ,那么   -   应该紧跟在   ^   之后。

  3. ^   是一个元字符,淡只有它紧跟在   [   之后才是元字符。

# Python 语言
re.search(r"^[^0-9][0-9]$", "a7") != None # true

# 匹配 - 0 9 之外的字符
re.search(r"^[^-09]$", "-") != None  # true

# 匹配 0 ^ 1 2
re.search(r"^[0^12]$", "^") != None # true
re.search(r"^[\^012]$", "^") != None # true

字符组简记法

正则表达式提供了字符的简单记法,字符组简记法可以单独出现,也可以出现在字符组中。

  1. \d   等价于   [0-9]   ,其中的 d 表示数字;

  2. \w   表示单词字符, 并不完全等价于   [0-9A-Za-z]   ,还可以匹配下划线   _   字符;

  3. \s   等价于   \t\r\n\v\f   等空白字符 ,其中的 s 表示 空白字符;

  4. \D    \d   相反,   \S    \s   相反,   \W    \w   相反;

  5. .   可以匹配任意字符,但是不包括   \n ;

  6. 匹配所有字符可以使用 [\s\S]    [\d\D]    [\w\W]   表示。

# Python 语言
# 用在普通字符组中
re.search("^[\da-zA-Z]$", "8") != None  # true
# 用在排除型字符组中
re.search("^[^\w]$", "8") != None  # false
re.search("^[^\w]$", ",") != None  # true
# 反义
re.search("^[\W]$", ",") != None  # true
re.search("^[\W]$", "8") != None  # false

注意事项:

  1. 如果字符组出现了字符组简记法,最好不要单独出现 -   ,否则可能引起错误。比如   [\d-a]   让你迷惑。

  2. 以上说 \d    \w    \s   的匹配规则都是针对 ASCII 编码而言, 也称为 ASCII匹配规则。

字符组运算

有一些语言为字符组提供了字符组运算的功能,可以在字符组内部进行稽核运算。常见的语言有 Java、 .NET 等。

Java 字符组运算示例:
 
[[a-z]&&[^awiou]]

表示在 26 个小写的英文字母中,出去 5 个语音字母剩下的 21 个字母。

POSIX 字符组

以上内容都是由 Perl 语言延伸出来的正则表达式流派,称为 PCRE。除此之外,还有其他的流派,比如: POSIX。POSIX 定义了 UNIX 操作系统应当支持的功能。目前 Java 也支持 POSIX字符组,但是只能匹配 ASCII 字符。