W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
一些無聊的幼稚黑客在你的網(wǎng)站頁面表單中輸入文本”pyt???”,然后你想將這些字符清理掉。
文本清理問題會涉及到包括文本解析與數(shù)據(jù)處理等一系列問題。在非常簡單的情形下,你可能會選擇使用字符串函數(shù)(比如 str.upper()
和 str.lower()
)將文本轉(zhuǎn)為標(biāo)準(zhǔn)格式。使用 str.replace()
或者 re.sub()
的簡單替換操作能刪除或者改變指定的字符序列。你同樣還可以使用2.9小節(jié)的 unicodedata.normalize()
函數(shù)將unicode文本標(biāo)準(zhǔn)化。
然后,有時(shí)候你可能還想在清理操作上更進(jìn)一步。比如,你可能想消除整個(gè)區(qū)間上的字符或者去除變音符。為了這樣做,你可以使用經(jīng)常會被忽視的 str.translate()
方法。為了演示,假設(shè)你現(xiàn)在有下面這個(gè)凌亂的字符串:
>>> s = 'pyt???\fis\tawesome\r\n'
>>> s
'pyt???\x0cis\tawesome\r\n'
>>>
第一步是清理空白字符。為了這樣做,先創(chuàng)建一個(gè)小的轉(zhuǎn)換表格然后使用 translate()
方法:
>>> remap = {
... ord('\t') : ' ',
... ord('\f') : ' ',
... ord('\r') : None # Deleted
... }
>>> a = s.translate(remap)
>>> a
'pyt??? is awesome\n'
>>>
正如你看的那樣,空白字符t和f已經(jīng)被重新映射到一個(gè)空格。回車字符r直接被刪除。
你可以以這個(gè)表格為基礎(chǔ)進(jìn)一步構(gòu)建更大的表格。比如,讓我們刪除所有的和音符:
>>> import unicodedata
>>> import sys
>>> cmb_chrs = dict.fromkeys(c for c in range(sys.maxunicode)
... if unicodedata.combining(chr(c)))
...
>>> b = unicodedata.normalize('NFD', a)
>>> b
'pyt??? is awesome\n'
>>> b.translate(cmb_chrs)
'python is awesome\n'
>>>
上面例子中,通過使用 dict.fromkeys()
方法構(gòu)造一個(gè)字典,每個(gè)Unicode和音符作為鍵,對于的值全部為None。
然后使用 unicodedata.normalize()
將原始輸入標(biāo)準(zhǔn)化為分解形式字符。然后再調(diào)用 translate
函數(shù)刪除所有重音符。同樣的技術(shù)也可以被用來刪除其他類型的字符(比如控制字符等)。
作為另一個(gè)例子,這里構(gòu)造一個(gè)將所有Unicode數(shù)字字符映射到對應(yīng)的ASCII字符上的表格:
>>> digitmap = { c: ord('0') + unicodedata.digit(chr(c))
... for c in range(sys.maxunicode)
... if unicodedata.category(chr(c)) == 'Nd' }
...
>>> len(digitmap)
460
>>> # Arabic digits
>>> x = '\u0661\u0662\u0663'
>>> x.translate(digitmap)
'123'
>>>
另一種清理文本的技術(shù)設(shè)計(jì)到I/O解碼與編碼函數(shù)。這里的思路是先對文本做一些初步的清理,然后再結(jié)合 encode()
或者 decode()
操作來清除或修改它。比如:
>>> a
'pyt??? is awesome\n'
>>> b = unicodedata.normalize('NFD', a)
>>> b.encode('ascii', 'ignore').decode('ascii')
'python is awesome\n'
>>>
這里的標(biāo)準(zhǔn)化操作將原來的文本分解為單獨(dú)的和音符。接下來的ASCII編碼/解碼只是簡單的一下子丟棄掉那些字符。當(dāng)然,這種方法僅僅只在最后的目標(biāo)就是獲取到文本對應(yīng)ACSII表示的時(shí)候生效。
文本字符清理一個(gè)最主要的問題應(yīng)該是運(yùn)行的性能。一般來講,代碼越簡單運(yùn)行越快。對于簡單的替換操作,str.replace()
方法通常是最快的,甚至在你需要多次調(diào)用的時(shí)候。比如,為了清理空白字符,你可以這樣做:
def clean_spaces(s):
s = s.replace('\r', '')
s = s.replace('\t', ' ')
s = s.replace('\f', ' ')
return s
如果你去測試的話,你就會發(fā)現(xiàn)這種方式會比使用 translate()
或者正則表達(dá)式要快很多。
另一方面,如果你需要執(zhí)行任何復(fù)雜字符對字符的重新映射或者刪除操作的話,tanslate()
方法會非常的快。
從大的方面來講,對于你的應(yīng)用程序來說性能是你不得不去自己研究的東西。不幸的是,我們不可能給你建議一個(gè)特定的技術(shù),使它能夠適應(yīng)所有的情況。因此實(shí)際情況中需要你自己去嘗試不同的方法并評估它。
盡管這一節(jié)集中討論的是文本,但是類似的技術(shù)也可以適用于字節(jié),包括簡單的替換,轉(zhuǎn)換和正則表達(dá)式。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: