在Python中用空字符串替换奇怪的单引号(’)

10 投票
5 回答
20225 浏览
提问于 2025-04-17 02:09

我正在尝试使用 string.replace('’','') 来替换那个让人头疼的奇怪单引号字符:’(也叫 \xe2 或者 #8217)。但是当我运行这行代码时,出现了这个错误:

SyntaxError: Non-ASCII character '\xe2' in file

编辑:当我尝试替换从远程获取的CSV文件中的字符时,也会出现这个错误。

# encoding: utf-8

import urllib2

# read raw CSV data from URL
url = urllib2.urlopen('http://www.aaphoenix.org/meetings/aa_meetings.csv')
raw = url.read()

# replace bad characters
raw = raw.replace('’', "")

print(raw)

即使执行了上面的代码,打印结果中仍然存在那个不想要的字符。我也尝试了下面答案中的建议。我很确定这是编码问题,但我就是不知道该怎么解决,所以当然任何帮助都非常感谢。

5 个回答

3

这个文件是用Windows-1252编码的。这里的撇号U+2019在这种编码中表示为\x92。正确的做法是把文件解码成Unicode格式来处理:

data = open('aa_meetings.csv').read()
assert '\x92' in data
chars = data.decode('cp1252')
assert u'\u2019' in chars
fixed = chars.replace(u'\u2019', '')
assert u'\u2019' not in fixed

问题在于你在寻找一个UTF-8编码的U+2019,也就是\xe2\x80\x99,但这个编码在文件里并不存在。把它转换成Unicode就能解决这个问题。

像我这样使用Unicode字面量是一种简单的方法,可以避免这个错误。不过,如果你想直接编码这个字符,可以写成u'’'

Python 2.7.1
>>> u'’'
u'\u2019'
>>> '’'
'\xe2\x80\x99'
8

你需要在你的源文件中声明编码。把这段代码放在你代码的前两行之一:

# encoding: utf-8

如果你使用的编码不是UTF-8(比如说Latin-1),那就把那个编码写上去。

13

这里的问题出在你下载的文件的编码上(aa_meetings.csv)。服务器在它的HTTP头中没有声明编码,但文件中唯一一个非ASCII字符的值是0x92。你说这个字符是“让人头疼的奇怪单引号”,因此这个文件的编码是windows-1252。但是你却在尝试用UTF-8编码的U+2019来进行搜索和替换,也就是'\xe2\x80\x99',这和文件里的内容不一样。

解决这个问题其实很简单,只需要在代码中添加适当的encodedecode调用就可以了:

# encoding: utf-8
import urllib2

# read raw CSV data from URL
url = urllib2.urlopen('http://www.aaphoenix.org/meetings/aa_meetings.csv')
raw = url.read().decode('windows-1252')

# replace bad characters
raw = raw.replace(u'’', u"'")

print(raw.encode("ascii"))

1这里提到的“ASCII”是指“将值从0x00到0x7F的单字节直接映射到U+0000到U+007F的字符编码,并且不定义值在0x80到0xFF之间的字节的含义”。

撰写回答