Python 将非ASCII字符替换为单个空格
我需要用空格替换所有非ASCII(\x00-\x7F)字符。我很惊讶,这在Python中并不容易,除非我遗漏了一些东西。以下函数仅删除所有非ASCII字符:Python 将非ASCII字符替换为单个空格,python,unicode,encoding,ascii,Python,Unicode,Encoding,Ascii,我需要用空格替换所有非ASCII(\x00-\x7F)字符。我很惊讶,这在Python中并不容易,除非我遗漏了一些东西。以下函数仅删除所有非ASCII字符: def remove_non_ascii_1(text): return ''.join(i for i in text if ord(i)<128) new_string = old_string.encode('ascii',errors='ignore') 如何用一个空格替换所有非ASCII字符? ,另外寻址非特定
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
new_string = old_string.encode('ascii',errors='ignore')
如何用一个空格替换所有非ASCII字符?
,另外寻址非特定字符的所有非ascii字符。您的''。join()
表达式正在筛选,删除任何非ascii字符;您可以改用条件表达式:
return ''.join([i if ord(i) < 128 else ' ' for i in text])
请注意此处的+
。对于字符处理,请使用Unicode字符串:
PythonWin 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32.
>>> s='ABC马克def'
>>> import re
>>> re.sub(r'[^\x00-\x7f]',r' ',s) # Each char is a Unicode codepoint.
'ABC def'
>>> b = s.encode('utf8')
>>> re.sub(rb'[^\x00-\x7f]',rb' ',b) # Each char is a 3-byte UTF-8 sequence.
b'ABC def'
但请注意,如果字符串包含分解的Unicode字符(例如,单独字符和组合重音符号),则仍然会有问题:
对于您,我建议您使用与原始字符串最相似的表示形式: 然后可以在字符串中使用它:
remove_non_ascii("Ceñía")
Cenia
这个怎么样
def replace_trash(unicode_string):
for i in range(0, len(unicode_string)):
try:
unicode_string[i].encode("ascii")
except:
#means it's non-ASCII
unicode_string=unicode_string[i].replace(" ") #replacing it with a single space
return unicode_string
如果替换字符可以是“?”而不是空格,那么我建议
result=text.encode('ascii','replace')。decode()
:
作为一种本地且高效的方法,您不需要使用
ord
或任何字符循环。只需使用ascii
编码并忽略错误
以下仅删除非ascii字符:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
new_string = old_string.encode('ascii',errors='ignore')
现在,如果要替换已删除的字符,只需执行以下操作:
final_string = new_string + b' ' * (len(old_string) - len(new_string))
可能是为了一个不同的问题,但我提供了@Alvero答案的版本(使用unidecode)。我想在我的字符串上做一个“常规”条带,即字符串的开头和结尾是空白字符,然后用“常规”空格替换其他空白字符,即
"Ceñíaㅤmañanaㅤㅤㅤㅤ"
到
,
我们首先将所有非unicode空间替换为常规空间(并再次将其连接起来)
然后我们用python的普通拆分再次拆分,并去掉每个“位”
最后再次将它们连接起来,但前提是字符串通过if
测试
' '.join(stripped for stripped in s if stripped)
有了它,
就安全了ㅤㅤㅤㅤ塞尼亚ㅤ玛尼娜ㅤㅤㅤㅤ')当我们使用ascii()时,code>正确返回'Ceñía mañana'
它会转义非ascii字符,并且不会正确更改ascii字符。因此,我的主要想法是,它不会更改ascii字符,因此我会遍历字符串并检查字符是否已更改。如果它已更改,则用替换符替换它,您会给出什么。
例如:''(单个空格)或'?'(带问号)
结果:“h i”(中间只有一个空格)
语法:remove(str,非ascii替换符)
str=在这里,您将给出要使用的字符串。
non_ascii_replacer=在这里,您将给出要替换所有非ascii字符的替换符。我的问题是,我的字符串中包含类似于België的BelgiÃ
,以及欧元符号的€
。我不想用空格替换它们。但是用正确的符号本身
我的解决方案是string.encode('Latin1')。decode('utf-8')
哇,你真的花了很大的努力来显示这么多的链接。+1一天又一天!你似乎错过了这一个,我很想看到一个有问题的输入示例。@Stuart:谢谢,但这是我提到的第一个。@dstromberg:我在问题中提到了一个有问题的示例字符:–
。这是。@dstromberg:sleer;str.join()
需要一个列表(它将传递两次值),并且生成器表达式将首先转换为一个。给它一个列表理解会更快。请参阅。如果给它一个UTF-8字节字符串,第一段代码将为每个字符插入多个空格。@MarkRansom:我假设这是Python 3。“–
字符替换为3个空格”问题中暗示输入是bytestring(不是Unicode),因此使用python2(否则'.join
将失败)。如果OP希望每个Unicode码点有一个空格,则应首先将输入解码为Unicode。谢谢,这是一个重要的观察结果。如果您确实找到了处理组合标记的逻辑方法,我很乐意为这个问题添加一个悬赏。我想,只需删除组合标记,而保留未组合的字符单独使用是最好的。部分解决方案是使用ud.normalize('NFC',s)
组合标记,但并非所有组合都由单个代码点表示。您需要更智能的解决方案查看角色的ud.category()在Unicode中,可以跨越多个Unicode码点。\X
(扩展的grapheme集群)regex(受regex
模块支持)允许在这些字符上迭代(注意:)。这是一个有趣的建议,但它假设用户希望非ascii成为unidecode的规则。然而,这向提问者提出了一个后续问题,询问他们为什么坚持使用空格,或者用另一个字符替换?谢谢,这是一个很好的答案。这不适用于此问题,因为大多数数据我正在处理的t没有类似ASCII的表示形式。例如ותן
。但是,从一般意义上说,这很好,谢谢!是的,我知道这对这个问题不起作用,但我来到这里是为了解决这个问题,所以我想我只想分享我自己的问题的解决方案,我认为这对于一个人来说是非常常见的一直处理非ascii字符的s@dotancohen。过去类似的东西存在一些安全漏洞。只是要小心如何实现它!@AlvaroFuentes,从那时起如何处理/重写Python 3的精彩代码?错误:NameError:全局名称“unicode”未定义,尽管这是
new_string = old_string.encode('ascii',errors='ignore')
final_string = new_string + b' ' * (len(old_string) - len(new_string))
"Ceñíaㅤmañanaㅤㅤㅤㅤ"
"Ceñía mañana"
def safely_stripped(s: str):
return ' '.join(
stripped for stripped in
(bit.strip() for bit in
''.join((c if unidecode(c) else ' ') for c in s).strip().split())
if stripped)
''.join((c if unidecode(c) else ' ') for c in s)
(bit.strip() for bit in s.split())
' '.join(stripped for stripped in s if stripped)
def remove(x, replacer):
for i in x:
if f"'{i}'" == ascii(i):
pass
else:
x=x.replace(i,replacer)
return x
remove('hái',' ')