※ 引述《aster30 (紫苑)》之铭言:
: import re
: str = '万'
: print re.search('[万千百十]',str)
: 执行结果:<_sre.SRE_Match object at 0x04BF83D8>
: 这样会match
: str = '金'
: print re.search('[万千百十]',str)
: 执行结果:None
: str = '台'
: print re.search('[万千百十]',str)
: 执行结果:<_sre.SRE_Match object at 0x04BF8480>
: str = '台'
: print re.search('[万]',str)
: 执行结果:None
因为你用 Python 2 的 str, 且档案编码应该是 UTF-8 :p
Python 2 的 str 事实上是一个以字节为单位的 sequence
所以当你写 '台' 时, Python 内部看到的是(假设编码 UTF-8)'\xe5\x8f\xb0'
这也是为什么当你对它取长度时会看到奇怪的结果
print len('台') # 3
你列出这几个字的编码分别是
台 e5 8f b0
万 e8 90 ac
千 e5 8d 83
百 e7 99 be
十 e5 8d 81
金 e9 87 91
可以看到“台”“千”“十”都有 e5
所以当你 re.search('[万千百十]', '台') 时
Python 会找到 e5 这个字节相符
match = re.search('[万千百十]', '台')
print match.group(0) # '\xe5'
让 re 支援中文(或大多数用到复数字节字的语言)的方法是改用 unicode type
这个 type 的单位是 Unicode codepoint
所以台就是台、万就是万、千就是千(一个字), 不会变成三个字节
进而让比对逻辑正确
在 Python 2 的解法就是改用 u'' literal 来写你的字串
或者你可以直升 Python 3, 因为 str type 改成以 Unicode codepoint 为单位
就不会遇到这个 Guido 年轻犯下的错误 ;)