Re: [問題] 正規表達式可以用中文字嗎?

作者: uranusjr (←這人是超級笨蛋)   2015-12-21 13:24:15
※ 引述《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 年輕犯下的錯誤 ;)
作者: alibuda174 (阿哩不達)   2015-12-21 15:59:00
作者: cobrasgo (人魚線變成鮪魚線,超帥)   2015-12-22 00:02:00
哇塞玩這麼深啊…強
作者: hsnusonic (sonic)   2015-12-22 00:25:00
好強~感謝分享
作者: banyhong (=_=)   2015-12-22 16:15:00
好清楚的說明

Links booklink

Contact Us: admin [ a t ] ucptt.com