如何使python解释器正确处理字符串操作中的非ASCII字符?

ade*_*ard 100 python unicode

我有一个看起来像这样的字符串:

6 918 417 712
Run Code Online (Sandbox Code Playgroud)

修剪这个字符串的明确方法(据我理解Python)只是说字符串在一个名为的变量中s,我们得到:

s.replace('Â ', '')
Run Code Online (Sandbox Code Playgroud)

这应该够了吧.但当然它抱怨'\xc2'文件blabla.py 中的非ASCII字符未编码.

我永远不会理解如何在不同的编码之间切换.

这是代码,它实际上与上面相同,但现在它在上下文中.该文件在记事本中保存为UTF-8,并具有以下标头:

#!/usr/bin/python2.4
# -*- coding: utf-8 -*-
Run Code Online (Sandbox Code Playgroud)

代码:

f = urllib.urlopen(url)

soup = BeautifulSoup(f)

s = soup.find('div', {'id':'main_count'})

#making a print 's' here goes well. it shows 6Â 918Â 417Â 712

s.replace('Â ','')

save_main_count(s)
Run Code Online (Sandbox Code Playgroud)

它不过是s.replace......

for*_*ran 155

def removeNonAscii(s): return "".join(filter(lambda x: ord(x)<128, s))
Run Code Online (Sandbox Code Playgroud)

编辑:我的第一个冲动总是使用过滤器,但生成器表达式更高效(更短)...

def removeNonAscii(s): return "".join(i for i in s if ord(i)<128)
Run Code Online (Sandbox Code Playgroud)

请记住,这可以保证与UTF-8编码一起使用(因为多字节字符中的所有字节都将最高位设置为1).


Jas*_*n S 78

Python 2使用ascii源文件的默认编码,这意味着您必须在文件顶部指定另一个编码,以在文字中使用非ascii unicode字符.Python 3使用utf-8源文件的默认编码,因此这不是问题.

请参阅:http: //docs.python.org/tutorial/interpreter.html#source-code-encoding

要启用utf-8源编码,这将位于前两行之一:

# -*- coding: utf-8 -*-
Run Code Online (Sandbox Code Playgroud)

以上是在文档中,但这也有效:

# coding: utf-8
Run Code Online (Sandbox Code Playgroud)

其他考虑因素

  • 必须使用文本编辑器中的正确编码保存源文件.

  • 在Python 2中,unicode文字必须u在它之前有,如s.replace(u"Â ", u"")在Python 3中,只需使用引号.在Python 2中,您可以from __future__ import unicode_literals获取Python 3行为,但请注意这会影响整个当前模块.

  • s.replace(u"Â ", u"")如果s不是unicode字符串,也会失败.

  • string.replace 返回一个新字符串,不进行编辑,因此请确保您也使用了返回值

  • 你实际上只需要`#coding:utf-8`.` - * - `不是用于装饰,但你不太可能需要它.我认为那是旧壳. (4认同)

tru*_*ppo 32

>>> unicode_string = u"hello aåbäcö"
>>> unicode_string.encode("ascii", "ignore")
'hello abc'
Run Code Online (Sandbox Code Playgroud)

  • 我看到你得到的票数,但是当我尝试它时,它说:不.UnicodeDecodeError:'ascii'编解码器无法解码位置1中的字节0xc2:序数不在范围内(128).可能是我的orignal字符串不是unicode吗?好吧,无论如何.它需要 (4认同)
  • 不错,谢谢。我可以建议在结果上使用 .decode() 以在原始编码中获得它吗? (2认同)

Vis*_*ioN 16

以下代码将用问号替换所有非ASCII字符.

"".join([x if ord(x) < 128 else '?' for x in s])
Run Code Online (Sandbox Code Playgroud)


Ako*_*exx 6

使用正则表达式:

import re

strip_unicode = re.compile("([^-_a-zA-Z0-9!@#%&=,/'\";:~`\$\^\*\(\)\+\[\]\.\{\}\|\?\<\>\\]+|[^\s]+)")
print strip_unicode.sub('', u'6Â 918Â 417Â 712')
Run Code Online (Sandbox Code Playgroud)


Mar*_*nen 5

答案太迟了,但是原始字符串位于UTF-8中,对于NO-BREAK SPACE,'\ xc2 \ xa0'为UTF-8。只需将原始字符串解码为s.decode('utf-8')(\ xa0在Windows-1252或latin-1错误解码时显示为空格:

示例(Python 3)

s = b'6\xc2\xa0918\xc2\xa0417\xc2\xa0712'
print(s.decode('latin-1')) # incorrectly decoded
u = s.decode('utf8') # correctly decoded
print(u)
print(u.replace('\N{NO-BREAK SPACE}','_'))
print(u.replace('\xa0','-')) # \xa0 is Unicode for NO-BREAK SPACE
Run Code Online (Sandbox Code Playgroud)

输出量

6 918 417 712
6 918 417 712
6_918_417_712
6-918-417-712
Run Code Online (Sandbox Code Playgroud)