[] (中括号)用于描述正则表达式中的字符集,可以通过向字符集内部输入字符来自定义匹配的内容。
import re
regex1 = re.compile('[ABC]')
message1 = "Hello. This is ABC club. A man will serve you then."
print(regex1.findall(message1))
输出:[‘A’, ‘B’, ‘C’, ‘A’]
正则表达式会根据中括号里的任意一个字符进行匹配。
如果想要匹配的字符很多,例如所有的大写字母时,可以这样操作:(这里是为了演示字符集的用法)
regex2 = re.compile('[A-Z]')
message2 = "It's my DUTY to save your SOUL."
print(regex2.findall(message2))
输出:[‘I’, ‘D’, ‘U’, ‘T’, ‘Y’]
如果还想匹配其他的内容,例如数字和大写字母时:
regex3 = re.compile('[0-9A-Z]')
message3 = "There are 7 GOBLINS and 2 dwarves in my house! Help!"
print(regex3.findall(message3))
输出:[‘T’, ‘7’, ‘G’, ‘O’, ‘B’, ‘L’, ‘I’, ‘N’, ‘S’, ‘2’, ‘H’]
0-9,A-Z之间不分开。 如果想要匹配减号 ‘-’,使用转义字符 ‘\-’ 来代替。
继续研究这个字符集,我产生了一个疑问:能否使用 [A-z] 这样的顺序呢?
答案是肯定的。不过,这里会发生一些特别的事情:
regex4 = re.compile('[A-z]')
message4 = "ABC Z [^] abc z"
print(regex4.findall(message4))
regex5 = re.compile('[M-m]')
message5 = "KLMNO...klmno"
print(regex5.findall(message5))
输出:[‘A’, ‘B’, ‘C’, ‘Z’, ‘[’, ‘^’, ‘]’, ‘a’, ‘b’, ‘c’, ‘z’]
[‘M’, ‘N’, ‘O’, ‘k’, ‘l’, ‘m’]
嗯……好像上面插入了某些符号?
这里大概可以得到出来一个结论:对于 [(c1)-(c2)] 的结构,它是根据 ASCII 的顺序操作的,表示可以匹配 c1 到 c2 之间(包括 c1 和 c2)的所有字符。
让我们来验证一下:
regex6 = re.compile('[#-E]')
message6 = "Awesome! The last 5% M&M Candies (10 candies) are nice; I'll enjoy them!"
print(regex6.findall(message6))
输出:[‘A’, ‘5’, ‘%’, ‘&’, ‘C’, ‘(’, ‘1’, ‘0’, ‘)’, ‘;’, “’”]-----(最后一个是单引号)
查看一下 ASCII 表:
35 - # , 69 - E
33 - !,37 - %,38 - &,39 - ',40 - (,41 - )
48 - 0,49 - 1,53 - 5
59 - ;
65 - A,73 - I
于是基本上可以确定:字符集中,以 ‘-’ 为连接的字符顺序满足 ASCII 的排列规则,即:对于 [(c1)-(c2)],对应的 ASCII 值 c1 <= c2 时,匹配 c1 到 c2 之间的字符。
让我们做一个验证:如果把 [(c1)-(c2)] 的顺序交换,即 c1 的 ASCII 值小于 c2,会怎么样呢?
regex7 = re.compile('[a-Z]')
message7 = "Maybe it's wrong..."
print(regex7.findall(message7))
然后就会显示一长串的报错信息:
Process finished with exit code 1
大概意思就是:a-Z 不符合字符集匹配的顺序(因为 a - 97,而 Z - 90,a 的 ASCII 值大于 Z),从而引发了问题。