正则表达式——排除型字符组
1.5 排除型字符组
在方括号[…]中列出希望匹配的所有字符,这种字符组叫做"普通字符组",它的确非常方便。不过,也有些问题是普通字符组不能解决的。
给定一个由两个字符构成的字符串str,要判断这两个字符是否都是数字字符,可以用[0-9][0-9]来匹配。但是,如果要求判断的是这样的字符串--第一个字符不是数字字符,第二个字符才是数字字符(比如A8、x6) --应当如何办?数字字符的匹配很好处理,用[0-9]即可;"不是数字"则很难办--不是数字的字符太多了,全部列出几乎不可能,这时就应当使用排除型字符组。
排除型字符组(Negated Character Class)非常类似普通字符组[…],只是在开方括号[之后紧跟一个脱字符^,写作[^…],表示"在当前位置,匹配一个没有列出的字符"。所以[^0-9]就表示"0~9之外的字符",也就是"非数字字符"。那么,[^0-9][0-9]就可以解决问题了,如例1-13所示。
例1-13 使用排除型字符组
re.search(r"^[^0-9][0-9]$", "A8") != None # => True re.search(r"^[^0-9][0-9]$", "x6") != None # => True
排除型字符组看起来很简单,不过新手常常会犯一个错误,就是把"在当前位置,匹配一个没有列出的字符"理解成"在当前位置不要匹配列出的字符"两者其实是不同的,后者暗示"这里不出现任何字符也可以"。例1-14很清楚地说明:排除型字符组必须匹配一个字符,这点一定要记住。
例1-14 排除型字符组必须匹配一个字符
re.search(r"^[^0-9][0-9]$", "8") != None # => False re.search(r"^[^0-9][0-9]$", "A8") != None # => True
除了开方括号[之后的^,排除型字符组的用法与普通字符组几乎完全相同,唯一需要改动的是:在排除型字符组中,如果需要表示横线字符-(而不是用于"-范围表示法"),那么-应该紧跟在^之后;而在普通字符组中,作为普通字符的横线-应该紧跟在开方括号之后,如例1-15所示。
例1-15 在排除型字符组中,紧跟在^之后的-不是元字符
#匹配一个-、0、9之外的字符 re.search(r"^[^-09]$", "-") != None # => False re.search(r"^[^-09]$", "8") != None # => True #匹配一个0~9之外的字符 re.search(r"^[^0-9]$", "-") != None # => True re.search(r"^[^0-9]$", "8") != None # => False
在排除型字符组中,^是一个元字符,但只有它紧跟在[之后时才是元字符,如果想表示"这个字符组中可以出现^字符",不要让它紧挨着[即可,否则就要转义。例1-16给出了三个正则表达式,后两个表达式实质是一样的,但第三种写法很麻烦,理解起来也麻烦,不推荐使用。
例1-16 排除型字符组的转义
#匹配一个0、1、2之外的字符 re.search(r"^[^012]$", "^") != None # => True #匹配4个字符之一:0、^、1、2 re.search(r"^[0^12]$", "^") != None # => True #^紧跟在[之后,但经过转义变为普通字符,等于上一个表达式,不推荐 re.search(r"^[\^012]$", "^") != None # => True