【问题标题】:How to remove extended ascii using python?如何使用 python 删除扩展的 ascii?
【发布时间】:2009-11-06 05:54:07
【问题描述】:

在尝试修复 PML(Palm 标记语言)文件时,我的测试文件似乎包含非 ASCII 字符,这导致 MakeBook 抱怨。解决方案是去除 PML 中的所有非 ASCII 字符。

所以在尝试在 python 中解决这个问题时,我有

import unicodedata, fileinput

for line in fileinput.input():
    print unicodedata.normalize('NFKD', line).encode('ascii','ignore')

但是,这会导致错误,即行必须是“unicode,而不是 str”。这是一个文件片段。

\B1a\B \tintense, disordered and often destructive rage†.†.†.\t

目前还不太确定如何正确传入要处理的行。

【问题讨论】:

  • 是否要过滤掉任何 ASCII 值大于 255 的字符?
  • 严格来说,没有扩展 ASCII 这样的东西。 ASCII 定义从 0 到 127 的值。任何高于该值的值都只能被任意解释。也许您应该使用术语非ASCII字符
  • 相关:终端输出安全转义功能stackoverflow.com/questions/437476/…

标签: python ascii extended-ascii


【解决方案1】:

试试print line.decode('iso-8859-1').encode('ascii', 'ignore')——这应该更接近你想要的。

【讨论】:

  • 这似乎有效,尽管 MakeBook 现在抱怨非法控制代码。
  • @Jauder,你当然也可以删除控制代码,例如在上面的clean=''.join(c for c in line if ord(c)>=32) 之后(删除所有控制代码,包括换行符和回车 - 调整口味,我们真的不能这样做在不知道要删除哪些控制代码的情况下为您提供!-)。
  • @Alex,如果我知道,我会 =)。麻烦的是,我只使用了一个没有可用源的 Java prog,它只会发出一条神秘的错误消息。 gist.github.com/227882
  • 但理想情况下,我想删除虚假控制代码但保留 LF/CR。
  • @Jauder,很好,但我不知道哪些是“虚假的”。怎么样:spurious=set(chr(c) for c in range(32))-set('\r\n\t'),当然还有clean-''.join(c for c in line if c not in spurious,然后通过经验性尝试以交互方式调整spurious,直到它恰好是您需要删除的字符集。
【解决方案2】:

您希望将line 视为 ASCII 编码数据,因此答案是使用 ascii 编解码器将其解码为文本:

line.decode('ascii')

这将引发实际上不是 ASCII 编码的数据的错误。这是忽略这些错误的方法:

line.decode('ascii', 'ignore').

这会以unicode 实例的形式为您提供文本。如果您更愿意使用(ascii 编码的)数据而不是文本,您可以对其重新编码以获取 strbytes 实例(取决于您的 Python 版本):

line.decode('ascii', 'ignore').encode('ascii')

【讨论】:

    【解决方案3】:

    要删除非 ASCII 字符,请使用 line.decode(your_file_encoding).encode('ascii', 'ignore')。但也许您最好为它们使用 PLM 转义序列:

    import re
    
    def escape_unicode(m):
        return '\\U%04x' % ord(m.group())
    
    non_ascii = re.compile(u'[\x80-\uFFFF]', re.U)
    
    line = u'\\B1a\\B \\tintense, disordered and often destructive rage\u2020.\u2020.\u2020.\\t'
    print non_ascii.sub(escape_unicode, line)
    

    这会输出\B1a\B \tintense, disordered and often destructive rage\U2020.\U2020.\U2020.\t

    用正则表达式删除非ASCII和控制字符也很容易(转义后可以安全使用):

    regexp = re.compile('[^\x09\x0A\x0D\x20-\x7F]')
    regexp.sub('', line)
    

    【讨论】:

      【解决方案4】:

      在 Python 中读取文件时,您会得到字节字符串,在 Python 2.x 及更早版本中也称为“str”。您需要使用decode 方法将这些转换为“unicode”类型。例如:

      line = line.decode('latin1')
      

      用正确的编码替换“latin1”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-23
        • 2014-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-18
        • 2019-08-09
        • 2021-04-06
        相关资源
        最近更新 更多