py2下hbase的字符串編碼問(wèn)題(\xe7\xbc\x96)
最近在py2的環(huán)境下使用hbase裸扶,遇到了一個(gè)令人惱火的編碼問(wèn)題肤无。問(wèn)題字符串如下:
'\\XE6\\X89\\X80\\XE8\\XB0\\X93\\XE7\\X89\\XB9\\XE6\\XAE\\X8A\\XE5\\XAD\\X97\\XE7\\XAC\\XA6\\XEF\\XBC\\X8C\\XE5\\XB0\\XB1\\XE6\\X98\\XAF\\XE4\\XB8\\X80\\XE4\\XBA\\X9B\\XE6\\X9C\\X89\\XE7\\X89\\XB9\\XE6\\XAE\\X8A\\XE5\\X90\\XAB\\XE4\\XB9\\X89\\XE7\\X9A\\X84\\XE5\\XAD\\X97\\XE7\\XAC\\XA6\\X0D\\X0A2.\\XE5\\XAE\\X9A\\XE4\\XBD\\X8D\\XE7\\XAC\\XA6\\XE4\\XBD\\XBF\\XE6\\X82\\XA8\\XE8\\X83\\XBD\\XE5\\XA4\\X9F\\XE5\\XB0\\X86\\XE6\\XAD\\XA3\\XE5\\X88\\X99\\XE8\\XA1\\XA8\\XE8\\XBE\\XBE\\XE5\\XBC\\X8F\\XE5\\X9B\\XBA\\XE5\\XAE\\X9A\\XE5\\X88\\XB0\\XE8\\XA1\\X8C\\XE9\\XA6\\X96\\XE6\\X88\\X96\\XE8\\XA1\\X8C\\XE5\\XB0\\XBE\\XE3\\X80\\X82'
這是一段utf-8編碼后的字符串超凳,由三個(gè)字節(jié)組成一個(gè)中文。
比較坑的地方是在它每個(gè)字節(jié)碼前的雙反斜杠\\
一開(kāi)始,我希望將它的反斜杠去掉一個(gè),然后就可以交給py自己來(lái)處理了取募,然而由于反斜杠的轉(zhuǎn)義,嘗試了多種方式蟆技,未果玩敏。(難受.jpg)
在查詢了網(wǎng)上的一些處理方法后,發(fā)現(xiàn)基本都是按照三個(gè)字節(jié)來(lái)取质礼,然后做轉(zhuǎn)碼旺聚。
但是這里存在的幾個(gè)坑:
- 這段字符串中包含英文與數(shù)字,它們?cè)诶锩媸侵苯觾?chǔ)存的几苍,并沒(méi)有被編碼翻屈。
-
\r
\n
這類的特殊字符是單個(gè)字節(jié)儲(chǔ)存的,必須區(qū)分出來(lái)妻坝。
于是伸眶,只好使用我覺(jué)得比較蠢但又無(wú)可奈何的辦法,思路如下:
- 使用正則刽宪,按照三個(gè)字節(jié)取出
- 轉(zhuǎn)換中文編碼后替換原字符串
- 處理特殊字符的編碼
將這兩個(gè)坑給填了后厘贼,代碼如下:
import re
rule = "\\\\X\w{2}\\\\X\w{2}\\\\X\w{2}"
words = re.findall(rule, var)
for t in words:
new_txt = t.replace('\\X', '').decode('hex')
var = var.replace(t, new_txt)
var = var.replace('\\X0D', '\r').replace('\\X0A', '\n').replace('\\X09', '\t')
這段代碼比較簡(jiǎn)單:
rule
是正則的提取規(guī)則,按照三個(gè)字節(jié)提取圣拄,去除可能存在的單字節(jié)特殊字符
var
是需要處理的字符串
new_txt
是我們需要的中文
第7行
是使用中文替換掉原始的字節(jié)碼
第8行
是處理可能存在的指標(biāo)符
使用這段代碼轉(zhuǎn)換上文的那段字符后嘴秸,得到的結(jié)果如下:
所謂特殊字符,就是一些有特殊含義的字符
2.定位符使您能夠?qū)⒄齽t表達(dá)式固定到行首或行尾庇谆。
需求基本滿足了岳掐,不過(guò)需要注意的是,這里依然存在幾個(gè)問(wèn)題:
- 這段代碼不兼容py3饭耳。它的運(yùn)行環(huán)境為py2串述,py3下運(yùn)行是會(huì)報(bào)錯(cuò)的。原因還是在于他們對(duì)字符串編碼的默認(rèn)處理方式不同寞肖。
- 沒(méi)有考慮大小寫(xiě)纲酗。 這里對(duì)字節(jié)碼的替換規(guī)則默認(rèn)為替換大寫(xiě)的衰腌,實(shí)際中,它可能存在小寫(xiě)的情況觅赊。
- 特殊字符右蕊。 這里只對(duì)常見(jiàn)的
\r
\n
\t
進(jìn)行了處理,實(shí)際中吮螺,還可能存在\f
\v
等的情況饶囚。
這里留下了幾個(gè)bug… 有點(diǎn)慚愧,不過(guò)正所謂前人挖坑后人填鸠补。
處理的方式其實(shí)也不難坯约,第2點(diǎn),使用正則來(lái)代替replace莫鸭,第3點(diǎn)闹丐,增加\f
\v
的處理即可,基本不用修改太多被因。第1點(diǎn)的話卿拴,則可能需要一點(diǎn)時(shí)間針對(duì)py3下的進(jìn)行改寫(xiě)了,不過(guò)問(wèn)題也不大梨与。
:)