2012-06-12 475 views
127

我目前使用美麗的湯來解析一個HTML文件,並呼籲get_text(),但它似乎是我留下了很多\ xa0代表空格的Unicode。有沒有一種有效的方法在Python 2.7中刪除它們,並將它們更改爲空格?我想更普遍的問題是,有沒有辦法去除Unicode格式?Python:從字符串中刪除 xa0?

我試過使用:line = line.replace(u'\xa0',' '),正如另一個線程所建議的那樣,但是把\ xa0改成了u,所以現在我到處都是「u」。 ):

編輯:問題似乎通過str.replace(u'\xa0', ' ').encode('utf-8')解決,但只是做.encode('utf-8')沒有replace()似乎導致它吐出甚至超出字符,\ xc2例如。任何人都可以解釋嗎?

+2

'str.replace('\ xa0','')'? –

+0

已經嘗試過,'ascii'編解碼器無法解碼位置0中的字節0xa0:序號不在範圍內(128) – zhuyxn

+11

包含Unicode。使用'''''而不是'''s。 :-) – jpaugh

回答

6

嘗試:

string.replace('\\xa0', ' ') 
+2

@RyanMartin:替換**四個字節**:len(b'\\ xa0')== 4'但是len(b'\ xa0')== 1'。如果可能的話;你應該修復產生這些轉義的上游。 – jfs

3

0XA0(Unicode)的是在0xC2A0 UTF-8。 .encode('utf8')只會將您的Unicode 0xA0替換爲UTF-8的0xC2A0。因此,0xC2s的幻影......編碼並沒有取代,因爲你現在可能已經意識到了。

+1

'0xc2a0'不明確(字節順序)。改爲使用'b'\ xc2 \ xa0''字節。 – jfs

129

\ xa0實際上是拉丁文1(ISO 8859-1)中的非破壞性空間,也是chr(160)。你應該用空格替換它。

string = string.replace(u'\xa0', u' ')

當.encode( 'UTF-8'),其將編碼的Unicode的爲UTF-8,這意味着每個unicode可通過1至4個字節來表示。對於這種情況,\ xa0由2個字節\ xc2 \ xa0表示。

請閱讀http://docs.python.org/howto/unicode.html

+2

我不知道有關Unicode和字符編碼的大量數據,但它看起來像[unicodedata.normalize](http://docs.python.org/2/library/unicodedata.html#unicodedata.normalize)將是比str.replace更合適 – dbr

+0

你的字符串是可行的建議,但是請注意,對這個字符串的所有引用也需要被替換。例如,如果您有一個打開文件的程序,並且其中一個文件的名稱中有一個非中斷空間,則除了執行此替換操作之外,還需要*重命名該文件。 – g33kz0r

+1

[U + 00a0是一個不可破壞的空格Unicode字符](http://codepoints.net/U+00a0),可以用latin1編碼將其編碼爲'b'\ xa0''字節,如兩個字節'b' \ xc2 \ xa0''以utf-8編碼。它可以用html表示爲' '。 – jfs

11

我遇到了這個問題,用python從sqlite3數據庫中提取一些數據。上面的答案對我來說不起作用(不知道爲什麼),但是確實如此:line = line.decode('ascii', 'ignore')但是,我的目標是刪除\ xa0s,而不是用空格替換它們。

我從this super-helpful unicode tutorial by Ned Batchelder.

+11

您現在正在移除任何不是ASCII字符的東西,您可能會掩蓋您的實際問題。使用''忽略''就像是通過換擋桿推動,即使你不明白離合器是如何工作的。 –

+0

@MartijnPieters鏈接的unicode教程很好,但你完全正確 - 'str.encode(... ,'ignore')'是'try:的Unicode處理等價物:... except:...'。雖然它可能隱藏錯誤信息,但它很少能解決問題。 – dbr

+1

爲處理EMAIL或URLS的某些目的,它似乎完美使用'.decode('ascii','ignore')' – andi

6

我這裏就結束了,而谷歌搜索與不可打印字符的問題得到了這一點。我使用MySQL UTF-8general_ci並處理波蘭語。對於有問題的字符串我必須procced如下:

text=text.replace('\xc2\xa0', ' ') 

這只是快速的解決方法,你probablly應該嘗試用正確的編碼設置的東西。

+1

如果'text'是一個表示使用utf-8編碼的文本的字符串,這將起作用如果您正在處理文本;先將它解碼爲Unicode('.decode('utf-8')')並進行編碼它只在最後一個字節串(如果API不直接支持Unicode,例如'socket')。文本上的所有中間操作應該以Unicode編碼。 – jfs

0

在Beautiful Soup中,您可以傳遞get_text() strip參數,該參數從文本的開頭和結尾剝離空白區域。這將刪除\xa0或任何其他空白,如果它出現在字符串的開頭或結尾。美麗的湯用\xa0替換了一個空字符串,這解決了我的問題。

mytext = soup.get_text(strip=True) 
+3

'strip = True'只有在' '處於文本的每一位的開始或結尾,如果它位於文本中的其他字符之間,則不會刪除該空格。 – jfs

7

嘗試使用.strip()在您的線路 line.strip()結束工作很適合我

87

有一個在Python的unicodedata庫很多有用的東西。其中之一是.normalize()功能。

嘗試:

new_str = unicodedata.normalize("NFKD", unicode_str) 

與任何上面,如果你沒有得到你之後的結果鏈接列出的其他方法更換NFKD。

+2

這太棒了。這應該是被接受的答案。 – Houman

+1

完全同意。簡單,清晰,簡短並且重點突出。豎起大拇指。 –

+0

這個伎倆。有一些HTML生成...微軟Word有很多奇怪的Unicode字符,並以某種方式清除它們。 –

3

試試這個代碼

import re 
re.sub(r'[^\x00-\x7F]+','','paste your string here').decode('utf-8','ignore').strip() 
0

嘗試幾種方法後,總結它,這是我做到了。以下是避免/從解析的HTML字符串中移除\ xa0個字符的兩種方法。

假設我們有原始的HTML如下:

raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>' 

所以讓我們嘗試清除該HTML字符串:

from bs4 import BeautifulSoup 
raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>' 
text_string = BeautifulSoup(raw_html, "lxml").text 
print text_string 
#u'Dear Parent,\xa0This is a test message,\xa0kindly ignore it.\xa0Thanks' 

上面的代碼字符串中產生這些字符\ XA0。要正確刪除它們,我們可以使用兩種方法。

方法#1(推薦): 第一個是BeautifulSoup的get_text方法與條參數作爲真 因此,我們的代碼變爲:

clean_text = BeautifulSoup(raw_html, "lxml").get_text(strip=True) 
print clean_text 
# Dear Parent,This is a test message,kindly ignore it.Thanks 

方法#2: 另一種選擇是使用Python的庫unicodedata

import unicodedata 
text_string = BeautifulSoup(raw_html, "lxml").text 
clean_text = unicodedata.normalize("NFKD",text_string) 
print clean_text 
# u'Dear Parent,This is a test message,kindly ignore it.Thanks' 

我也詳細介紹了這些方法on this blog你可能想參考。