替换ascii编码的字符串中的非ascii字符

时间:2015-09-22 20:42:12

标签: python string character-encoding

我有这个代码片段(Python 2.7):

from bs4 import BeautifulSoup

content = '  foo bar';
soup = BeautifulSoup(content, 'html.parser')
w = soup.get_text()

此时w的字节值为160,但其编码为ASCII

如何用另一个字符替换所有\ xa0字节?

我试过了:

w = w.replace(chr(160), ' ')
w = w.replace('\xa0', ' ')

但我收到了错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)

为什么BS会返回一个带有无效字符的ASCII编码字符串?

有没有办法将w转换为' latin1`编码的字符串?

1 个答案:

答案 0 :(得分:2)

  

此时w有一个值为160的字节,但它的编码是'ascii'。

你有一个unicode字符串:

>>> w
u'\xa0 foo bar'
>>> type(w)
<type 'unicode'>
  

如何用另一个字符替换所有\ xa0字节?

>>> x = w.replace(u'\xa0', ' ')
>>> x
u'  foo bar'
  

为什么BS会返回一个带有无效字符的'ascii'编码字符串?

如上所述,它不是ascii编码的字符串,而是Unicode字符串实例。

  

有没有办法将w转换为'latin1`编码的字符串?

不确定

>>> w.encode('latin1')
'\xa0 foo bar'

(注意这最后一个字符串是一个编码字符串,而不是一个unicode对象,它的表示形式不像前面的unicode对象那样以'u'为前缀。)

备注(已编辑):

  • 如果要在源文件中键入字符串,请注意源文件的编码很重要。 Python将假设您的源文件是ASCII。另一方面,命令行解释器将假定您正在以默认系统编码输入字符串。当然你可以覆盖所有这些。
  • 避免使用latin1,如果可能,请使用UTF-8:即。 w.encode('utf8')
  • 当编码和解码可以告诉Python ignore错误或replace个字符无法使用某些标记字符进行编码时。我不建议忽略编码错误(至少在没有记录它们的情况下),除非您知道存在编码错误或者需要将文本编码为更简化的字符集时需要更换代码点,这种情况很少见。无法表示(即如果您需要将'España'编码为ASCII,您肯定应该替换'ñ')。但是对于这些情况,有更好的选择,你应该研究神奇的unicodedata模块(见https://stackoverflow.com/a/1207479/401656)。
  • 有一个Python Unicode HOWTO:https://docs.python.org/2/howto/unicode.html