2011-03-24 306 views
6

下面是問題,我有一個unicode字符串作爲python sqlite查詢的輸入。查詢失敗('like')。原來這個字符串'FRANCE'沒有6個字符,它有7個字符。第七個是。 。 。 unicode U + FEFF,一個零寬度的不間斷空間。如何從Python字符串中去除unicode「標點符號」

在查詢之前,我究竟如何捕獲一類這樣的東西?

+1

我不知道這串是從哪裏來的。 – 2011-03-24 04:54:19

+0

這不是標點符號。它的存在表明一些上游過程的嚴重失敗。 – 2011-03-24 05:11:47

+0

說真的,你到底是如何以BOM作爲第七個字符的? – 2011-03-24 05:32:07

回答

10

您可以使用unicodedata類別,在Python Unicode數據表的一部分:

>>> unicodedata.category(u'a') 
'Ll' 
>>> unicodedata.category(u'.') 
'Po' 
>>> unicodedata.category(u',') 
'Po' 

的類別punctation字符開始'P',你可以看到。 所以你需要通過字符過濾你的字符(使用列表理解)。

參見:

你的情況

>>> unicodedata.category(u'\ufeff') 
'Cf' 

所以,你可以基於該類別的字符一些白名單。

+0

感謝所有這些建議。他們最有用! – 2011-03-26 22:20:49

+0

哦,是的,在回答其他評論中的問題時,源字符串來自網頁(如您所知,任何事情都可能發生)。 – 2011-03-26 22:22:30

+0

+1爲一個很好的答案。這讓我覺得這是正確的做法。 – 2011-05-12 21:41:11

0

這也是字節順序標記BOM。只是清理你的字符串首先消除這些,使用類似:


>>> f = u'France\ufeff' 
>>> f 
u'France\ufeff' 
>>> print f 
France 
>>> f.replace(u'\ufeff', '') 
u'France' 
>>> f.strip(u'\ufeff') 
u'France' 
+0

這不會刪除任意的「垃圾字符」。 – 2011-03-24 04:53:14

+0

這是真的。我只是解決了所描述的一個問題。 – 2011-03-24 04:54:52

+1

它只是一個字符串開頭的BOM。 – 2011-03-24 05:07:24

1

一般來說,如果您可以爲您的用例定義這樣的事情,則應該使用允許字符的白名單進行輸入驗證。然後,您只需扔掉不在白名單上的任何東西(或完全拒絕輸入)。

如果你可以定義了一組允許的字符,那麼你可以使用正則表達式去除其他所有內容。

例如,假設你知道「國家」只會有大寫的英文字母和空格,你可以去掉一切,包括你討厭的unicode的信是這樣的:

>>> import re 
>>> country = u'FRANCE\ufeff' 
>>> clean_pattern = re.compile(u'[^A-Z ]+') 
>>> clean_pattern.sub('', country) 
u'FRANCE' 

如果能't定義了一系列允許使用的字符,因此您將面臨很大的麻煩,因爲預測可能會拋出的所有數以萬計的意外unicode字符將成爲您的任務 - 並且越來越多的字符被添加到規格中因爲語言多年來一直在發展。

+1

哦,這個白名單方法不限於使用正則表達式。如果你對「任何不是標點符號的任何unicode字符」都可以,那麼你可以迭代字符串來檢查字符unicodedata.category(...)pynator建議。 – Nathan 2011-03-24 05:01:50

相關問題