使用Python去除字符串中的不间断空格

40

我在Python中遇到了一个非常基本的字符串问题(我无法解决)。基本上,我正在尝试执行以下操作:

'# read file into a string 
myString =  file.read()

'# Attempt to remove non breaking spaces 
myString = myString.replace("\u00A0"," ")

'# however, when I print my string to output to console, I get: 
Foo **<C2><A0>** Bar

我之前认为"\u00A0"是表示Unicode不间断空格的转义码,但是似乎我没有正确地使用它。你们有什么想法,我做错了什么吗?


3
你使用的是哪个版本的Python(答案可能因为你使用的是2.x还是3.x而不同)? - Kathy Van Stone
嗨,Kathy,是的,我正在使用Python v2.5.1。 - dontsaythekidsname
回应中编辑了我的答案。 - Kathy Van Stone
7个回答

57

你没有一个Unicode字符串,而是一个UTF-8字节列表(在Python 2.x中,它们是字符串)。

尝试使用

myString = myString.replace("\xc2\xa0", " ")

更好的做法是切换到Unicode - 参见这篇文章获取想法。因此,您可以说:
uniString = unicode(myString, "UTF-8")
uniString = uniString.replace(u"\u00A0", " ")

它应该也可以工作(注意:我现在没有Python 2.x可用),但是当您将其发送到文件或打印到屏幕时,您需要将其转换回字节(二进制)。


1
你的解决方案非常有帮助。谢谢! - Rokujolady
你的UTF-8解决方案正是我需要的,可以将非断行空格插入日志文件中。虽然当记录器将日志记录回显到控制台时,输出看起来很奇怪,因为控制台不是UTF-8格式,但它在日志文件中完全不可见,使其出现在我需要的位置,我的列标签上面有一个空白行。 - David A. Gray
看起来这个网站已经消失了。我会去寻找其他的选择。 - Kathy Van Stone
在Python 3中是否需要使用unicode()函数或u""?我问这个问题是因为我的理解是Python 3将任何字符串都编码为Unicode。 - Celdor
这个答案绝对是2.x的答案——Python 3处理字符串的方式不同。 - Kathy Van Stone

12

我在给一个旧问题添加答案之前犹豫了一下,但由于Python3将Unicode“不间断空格”字符计为空格字符,并且字符串默认为Unicode,因此您可以使用joinsplit来消除字符串s中的非间断空格,就像这样:

s = ' '.join(s.split())

当然,这也会改变任何其他空白字符(制表符、换行符等)。您可以在维基百科上的空格字符页面中找到将被更改的Unicode字符列表。

请注意,这仅适用于Python3。


1
2022年这个无法工作。 - TheConfax
1
2022年它是以何种方式无法工作的?你尝试了哪个版本的python3 - Thruston
@Thruston 这种方法对于以下字符串 abc999\u202c 不起作用。但我不确定 \u202c 是否为不间断空格。你有任何想法吗?谢谢。 - Huy Truong
这是因为PDF字符= u202c不是空格。请参阅https://www.fileformat.info/info/unicode/char/202c/index.htm。您可以尝试使用https://pypi.org/project/Unidecode/。 - Thruston
@TheConfax 使用 ord() 函数并仔细检查,清除 UC_160 空格对我有用! - Yu Da Chi

7
不,u"\u00A0"是不间断空格的转义代码。"\u00A0"是6个字符,不是任何转义代码。请阅读这篇文章

1
你提供的链接对于初学者可能很有用,但它是误导性的。它完全忽略了Unicode规范化,例如,'ć'u'\u0107',它可以表示为 u'c\u0301'。详见 http://unicode.org/reports/tr15/。 - jfs

5

请注意,一个简单的myString.strip()不仅会删除空格,还会从myString的开头和结尾删除非断行空格。虽然不完全符合OP的要求,但在许多情况下仍非常有用。


4
您可以通过强制编码来简单解决此问题。
 cleaned_string = myString.encode('ascii', 'ignore')

3

请注意Python的空格正则表达式字符会匹配非中断空格。

以下代码将使用单个空格替换一个或多个空格/非中断空格。

import re

re.sub(r'\s+', ' ', u"String with    spaces and non\u00A0breaking\u00A0spaces")
# 'String with spaces and non breaking spaces'

0

从你的写作中没有任何迹象表明你做错了什么:如果原始字符串在“Foo”和“Bar”之间有一个不间断空格,那么现在你只是有一个普通的空格。这假设你已经将输入字符串(我想象是一个字节串,除非你使用的是Python 3或file是使用codecs模块中的函数打开的)解码为Unicode字符串,否则你不太可能在非Unicode字节字符串中找到Unicode字符,以便进行replace操作。但是,你写的内容中没有明显的问题迹象。

你能澄清一下输入是什么(在替换之前打印repr(myString)),输出是什么(在替换之后再次打印repr(myString)),以及为什么你认为这是个问题吗?没有repr,实际上不同的字符串可能看起来相同,但repr可以帮助解决这个问题。


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