顾名思义,字符组(character class)就是一组字符,在正则表达式中,它表示“在同一个位置可能出现的各种字符”,其写法是在一对方括号之间列出所有可能出现的字符,简单的字符组比如[ab]
、[1234]
、[#.?]
在解决一些常见问题时可以大大简化操作。
字符可以分为很多累,比如数字、字母、标点等。有时候要求“只出现一个数字”,换句话说,这个歌位置上的字符只能是0-9折十个字符之一。
例1-2 使用正则表达式判断数字字符
re.search("[0123456789]", '3') != None # True
字符组中字符的排列顺序并不影响字符组的功能,出现重复字符也不会影响。所以[123]
、[112233]
、[3321]
是等价的。但是一般不推荐在字符组中出现重复字符,并且,还应该让字符组中的字符排列更符合认知习惯,比如[0123456789]
就好过[9876543210]
。为此,正则表达式提供了范围表示法(range),它更加直观且简化。
所谓“范围表示法”,就是用[x-y]
表示x到y整个范围内的字符,省去一一列出的麻烦。比如[12345]
可以表示为[1-5]
,[abcdefghijk]
可以表示为[a-k]
。
在字符组中,-
表示的范围,一般是根据字符对应的码值(code point,也就是字符在对应编码表中编码的数值)来确定的,码值小的字符在前,码值大的字符在后。在ascii编码中,字符0的码值是48,字符9点码值是57,所以[0-9]
等价于[0123456789]
,而[9-0]
是错误的范围,因为9点码值大于0的码值,所以会报错。
在字符组中可以同时并列多个“-范围表示法”,字符组[0-9A-Za-z]
可以匹配数字和大小写字母。
在ascii编码中,09的码值是48~57,A-Z的码值是65~90,az的码值是97~122。
不少语言中,可以用转义序列\xhex_num
来表示一个字符,其中\x
是固定前缀,表示转义序列的开头,hex_num
是字符对应的码值,是一个两位的十六进制数值。比如A的ascii码值是41(十进制65),所以可以用\x41
表示。
re.search("\x41", 'A') is not None # True
re.search("\x61", 'a') is not None # True
字符组中有时会出现这种表示法,它可以表现一些难以输入或者难以显示的字符,比如\x7F
;也可以用来方便地表示某个范围,比如所有ASCII字符对应的字符组是[\x00-\x7F]
。
all(re.search("^[\x00-\x7F]$", x) for x in ['c', 'I', '0', '<']) # True