[^[:print:]]和[[:cntrl:]]有什么区别吗?

0 投票
1 回答
1852 浏览
提问于 2025-04-18 17:12

我在尝试弄清楚上面提到的POSIX字符组之间是否有实际的区别,或者更具体地说,以下这两个模式之间是否有不同:

r'[^[\x20-\x7E]]'  # Match All non-printable
r'[\x00-\x1F\x7F]'  # Match control characters 

1 个回答

2

我不太确定POSIX组的情况(反正Python的正则表达式引擎不支持它们),但是

r'[^[\x20-\x7E]]'

这个写法肯定是错的(应该是r'[^\x20-\x7E]'),而且匹配的内容远远超过了

r'[\x00-\x1F\x7F]'

因为后者只考虑ASCII字符,而前者还会匹配代码点126以上的任何东西:

>>> r1 = re.compile(r'[^\x20-\x7E]')
>>> r2 = re.compile(r'[\x00-\x1F\x7F]')
>>> r1.match("ä")
<_sre.SRE_Match object; span=(0, 1), match='ä'>
>>> r2.match("ä")
>>>

为了进一步解释我上面提到的为什么你的正则表达式r'[^[\x20-\x7E]]'有问题:它会匹配一个既不是左方括号也不在ASCII 20到ASCII 126范围内的字母(而且这个范围已经包含了[),并且后面跟着一个字面上的右方括号:

>>> r1 = re.compile(r'[^[\x20-\x7E]]')
>>> r1.match("\x00")
>>> r1.match("\x00]")
<_sre.SRE_Match object; span=(0, 2), match='\x00]'>

撰写回答