在Python中替换特殊字符

3

我从网页上获取到以下文本:

£6.49

显然,我希望它显示为:

£6.49

到目前为止,我尝试了以下方法:

s = url['title']
s = s.encode('utf8')
s = s.replace(u'Â','')

以下是一些变体(在同一个论坛上找到的):

但仍然没有运气,因为我不断收到以下错误信息:

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

有人能帮我解决这个问题吗?

更新:

添加repr示例和内容类型。

u'Star Trek XI £3.99'
u'Oscar Winners Best Pictures Box Set \xc2\xa36.49'
Content-Type: text/html; charset=utf-8

提前感谢您。

为什么从网络上获取的文本格式如此糟糕? - ondra
1
请发布来自网络的字符串的 repr(...) 。那么我们就能确切地知道我们要处理什么。 - unutbu
也许公布“Content-Type”标题会有所帮助:“response=urllib2.urlopen(url);content_type=response.headers.getheader('Content-Type')” - unutbu
更新了一些我收到的示例代码。 - Marcos Placona
1
顺便问一下,你应该使用“解码”而不是“编码”吧? - ondra
显示剩余2条评论
2个回答

7
如果,s = url ['title'] 使 s 等于这个:
In [48]: s=u'Oscar Winners Best Pictures Box Set \xc2\xa36.49'

那么问题就在于:

  1. 定义url的代码中存在问题,
  2. 或者来自网络的内容格式不正确。

如果是情况1,我们需要查看定义url的代码。

如果是情况2,一个快速而简单的解决方法是使用raw-unicode-escape编解码器对Unicode对象s进行编码:

In [49]: print(s)
Oscar Winners Best Pictures Box Set £6.49

In [50]: print(s.encode('raw-unicode-escape'))
Oscar Winners Best Pictures Box Set £6.49

另请参阅此SO问题


关于像 s=u'Star Trek XI £3.99' 这样的标题:再次强调,在达到这个阶段之前解决问题会很好——也许可以通过查看 url 的定义方式来解决。但是假设从网络获取的内容存在格式错误,可以采用以下解决方法:
In [86]: import re

In [87]: print(re.sub(r'&#x([a-fA-F\d]+);',lambda m: unichr(int(m.group(1),base=16)),s))
Star Trek XI £3.99

一点解释:
请注意

In [51]: x=u'£'
In [53]: x.encode('utf-8')
Out[53]: '\xc2\xa3'

因此,使用 utf-8 编解码的 Unicode 对象 u'£' 变成了字符串对象 '\xc2\xa3'
不知何故,url['title'] 被定义为 Unicode 对象 u'\xc2\xa3'。(u 的存在很重要!)
因此,我们得到了 u'\xc2\xa3',但我们需要的是 '\xc2\xa3'。使用 raw-unicode-escape 编解码 Unicode 对象 u'\xc2\xa3' 将其转换为 '\xc2\xa3'

嗨,我们快要成功了,你的代码对第二个字符串起作用了,但是第一个字符串仍然显示错误(星际迷航 XI £3.99)。 - Marcos Placona

0

编辑:你的对象已经是Unicode格式了。在我看来,实际上没有必要使用编码/解码。

>>> print u'Oscar Winners Best Pictures Box Set \xc2\xa36.49'.replace(u'Â','')
Oscar Winners Best Pictures Box Set £6.49

然而,对我来说似乎有些不对劲。Unicode对象实际上并不是Unicode;请参见:

>>> print 'Oscar Winners Best Pictures Box Set \xc2\xa36.49'.decode('utf8')
Oscar Winners Best Pictures Box Set £6.49

你发布的 repr() 不应该是 Unicode 对象。这就是我问你从哪里获取数据的原因,可能有些地方出了问题。

UnicodeEncodeError: 'ascii' 编解码器无法对第100-101个字符进行编码:该值不在128的范围内。 - Marcos Placona
你应该发布此失败的字符串的repr()和特定行(即它在解码时失败吗?)。 - ondra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接