Python:从字符串中删除\ xa0?


241

我目前正在使用Beautiful Soup解析HTML文件并调用get_text(),但似乎我剩下很多表示空格的\ xa0 Unicode。有没有一种有效的方法可以在Python 2.7中将其全部删除,并将其更改为空格?我想更笼统的问题是,有没有办法删除Unicode格式?

我尝试使用:line = line.replace(u'\xa0',' '),如另一个线程所建议的那样,但是将\ xa0更改为u,所以现在到处都是“ u”。):

编辑:问题似乎已通过解决str.replace(u'\xa0', ' ').encode('utf-8'),但.encode('utf-8')不这样做replace()似乎会导致它吐出甚至更奇怪的字符,例如\ xc2。谁能解释一下?


已经尝试过,'ascii'编解码器无法在位置0解码字节0xa0:序数不在range(128)中
zhuyxn 2012年

15
接受Unicode。使用u''s而不是''s。:-)
jpaugh 2012年

1
尝试使用str.replace(u'\ xa0',''),但到处都是“ u”而不是\ xa0s:/
zhuyxn 2012年

如果字符串是unicode,则必须使用u' '替换而不是' '。原始字符串是unicode吗?
pepr 2012年

Answers:


267

\ xa0实际上是Latin1(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上阅读。

请注意:此答案自2012年起,Python仍在继续,您unicodedata.normalize现在应该可以使用


11
我对Unicode和字符编码不了解很多。但是,似乎unicodedata.normalize比str.replace更合适
dbr

对于字符串,您的建议是可行的,但请注意,对该字符串的所有引用也将需要替换。例如,如果您有一个打开文件的程序,并且其中一个文件的名称具有不间断的空格,则除了执行此替换操作外,还需要重命名该文件。
g33kz0r 2014年

1
U + 00a0是不可破坏的空间Unicode字符,可以将其编码为b'\xa0'latin1编码的字节,也可以编码为b'\xc2\xa0'utf-8编码的两个字节。可以用 html 表示。
jfs 2015年

3
当我尝试这个时,我得到UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 397: ordinal not in range(128)
gwg

被困了1个小时,终于解决了。非常感谢。
萨德曼·哈桑

217

Python unicodedata库中有许多有用的东西。功能之一就是它.normalize()

尝试:

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

如果您没有得到想要的结果,请使用上面链接中列出的任何其他方法替换NFKD。


9
这真是太好了。这应该是公认的答案。
侯曼

2
完全同意。简单,清晰,简短而切合实际的解决方案。竖起大拇指。
比利·洪

2
不太确定,您可能要normalize('NFKD', '1º\xa0dia')返回“
1ºdia


1
啊,如果文字是'KOREAN',请不要尝试。네요가전부리네요。
Cho

18

尝试在行尾使用.strip() line.strip()对我来说效果很好


15

在尝试了几种方法之后,总结一下,这就是我的方法。以下是避免/从解析的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方法,带参数为True, 因此我们的代码变为:

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'

我还在此博客上详细介绍了这些方法,您可能想参考这些方法。


谢谢,方法1是我一直在寻找的东西。
Vasim

12

试试这个:

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

5
@RyanMartin:这将替换四个字节len(b'\\xa0') == 4但是len(b'\xa0') == 1。如果可能的话; 您应该修复会产生这些转义的上游。
jfs 2015年

12

我遇到了同样的问题,使用python从sqlite3数据库中提取了一些数据。上面的答案对我不起作用(不确定为什么),但是这样做:line = line.decode('ascii', 'ignore')但是,我的目标是删除\ xa0s,而不是用空格替换。

我是从Ned Batchelder的这个超级有用的unicode教程中得到的。


14
现在,您要删除所有不是ASCII字符的内容,可能是在掩盖您的实际问题。'ignore'即使您不了解离合器的工作原理,使用就像推变速杆一样。–
马丁·彼得斯

@MartijnPieters链接的unicode教程不错,但是您完全正确- str.encode(..., 'ignore')是Unicode处理的try: ... except: ...。尽管它可能隐藏错误消息,但很少解决问题。
2013年

1
出于某些目的,例如处理EMAIL或URLS,似乎非常适合使用.decode('ascii', 'ignore')
andilabs 2014年

1
samwize的答案对您不起作用,因为它适用于Unicode字符串。line.decode()在你的答案表明,你的输入是字节串(你不应该叫.decode()上一个Unicode字符串(去执行,该方法在Python 3移除)。我不明白它是如何可以看到您已经教程链接到您的答案中,错过了字节和Unicode之间的差异(请勿混用)
jfs 2015年

8

我在这里搜索无法打印的字符时遇到了问题。我使用MySQL UTF-8 general_ci并处理波兰语。对于有问题的字符串,我必须按以下步骤进行:

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

这只是一个快速的解决方法,您可能应该尝试使用正确的编码设置进行操作。


1
如果text是代表使用utf-8编码的文本的字节串,则此方法有效。如果您正在处理文本;首先将其解码为Unicode,.decode('utf-8')并仅在最后将其编码为字节串(如果API不直接支持Unicode,例如socket)。对文本的所有中间操作都应在Unicode上执行。
jfs 2015年

8

试试这个代码

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

4

UTF-8中的0xA0(Unicode)为0xC2A0。.encode('utf8')只会采用您的Unicode 0xA0并替换为UTF-8的0xC2A0。因此,0xC2s的出现……编码并没有取代,正如您现在可能已经意识到的那样。


1
0xc2a0是不明确的(字节顺序)。请改用b'\xc2\xa0'字节字面量。
jfs 2015年

3

这等效于空格字符,因此将其删除

print(string.strip()) # no more xa0

1

在Beautiful Soup中,您可以传递get_text()strip参数,该参数从文本的开头和结尾去除空白。\xa0如果它出现在字符串的开头或结尾,它将删除或任何其他空格。Beautiful Soup用一个空字符串替换了\xa0,这为我解决了问题。

mytext = soup.get_text(strip=True)

5
strip=True&nbsp;在文本每一行的开头或结尾处有效。如果空格位于文本中其他字符之间,则不会删除空格。
jfs 2015年

1

具有正则表达式的通用版本(它将删除所有控制字符):

import re
def remove_control_chart(s):
    return re.sub(r'\\x..', '', s)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.