我需要用空格替换所有非ascii (\x00-\x7F)字符。我很惊讶,这在Python中不是非常容易的,除非我遗漏了什么。下面的函数简单地删除所有非ascii字符:

def remove_non_ascii_1(text):

    return ''.join(i for i in text if ord(i)<128)

这一个替换非ascii字符与空格的数量在字符编码点的字节数(即-字符替换为3个空格):

def remove_non_ascii_2(text):

    return re.sub(r'[^\x00-\x7F]',' ', text)

如何用一个空格替换所有非ascii字符?

在无数类似的SO问题中,没有一个是针对字符替换而不是剥离的,另外是针对所有非ascii字符而不是特定字符。


当前回答

我的问题是我的字符串包含了像BelgiÃ的België和&#x20AC的€符号。我不想把它们换成空格。但要有正确的符号。

我的解决方案是string.encode('Latin1').decode('utf-8')

其他回答

你的" .join()表达式正在过滤,删除任何非ascii的东西;你可以使用条件表达式:

return ''.join([i if ord(i) < 128 else ' ' for i in text])

这将逐个处理字符,并且仍然会使用一个空格替换每个字符。

你的正则表达式应该用空格替换连续的非ascii字符:

re.sub(r'[^\x00-\x7F]+',' ', text)

注意这里的+。

这个怎么样?

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

我的问题是我的字符串包含了像BelgiÃ的België和&#x20AC的€符号。我不想把它们换成空格。但要有正确的符号。

我的解决方案是string.encode('Latin1').decode('utf-8')

可能是为了一个不同的问题,但我提供了@Alvero的答案(使用unidecode)的我的版本。我想在我的字符串上做一个“常规”剥离,即空白字符的字符串的开始和结束,然后用“常规”空间替换仅其他空白字符,即。

"Ceñíaㅤmañanaㅤㅤㅤㅤ"

to

"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)

我们首先将所有非unicode空格替换为常规空格(并再次将其连接),

''.join((c if unidecode(c) else ' ') for c in s)

然后我们再次用python的正常拆分,剥离每个“位”,

(bit.strip() for bit in s.split())

最后将它们重新连接起来,但前提是字符串通过了if测试,

' '.join(stripped for stripped in s if stripped)

correctly returns ' Cenia manana '。

使用Raku(以前称为Perl_6)进行预处理

~$ raku -pe 's:g/ <:!ASCII>+ / /;' file

样例输入:

Peace be upon you
السلام عليكم
שלום עליכם
Paz sobre vosotros

样例输出:

Peace be upon you


Paz sobre vosotros

注意,你可以使用下面的代码获得大量的匹配信息:

~$ raku -ne 'say s:g/ <:!ASCII>+ / /.raku;' file
$( )
$(Match.new(:orig("السلام عليكم"), :from(0), :pos(6)), Match.new(:orig("السلام عليكم"), :from(7), :pos(12)))
$(Match.new(:orig("שלום עליכם"), :from(0), :pos(4)), Match.new(:orig("שלום עליכם"), :from(5), :pos(10)))
$( )
$( )

或者更简单地说,你可以想象一下替换的空格:

~$ raku -ne 'say S:g/ <:!ASCII>+ / /.raku;' file
"Peace be upon you"
"   "
"   "
"Paz sobre vosotros"
""

https://docs.raku.org/language/regexes#Unicode_properties https://www.codesections.com/blog/raku-unicode/ https://raku.org