【问题标题】:Stripping a unicode text of whatever is not a character剥离非字符的 unicode 文本
【发布时间】:2012-12-18 18:25:37
【问题描述】:

我正在尝试编写一个简单的 Python 脚本,该脚本将文本文件作为输入,删除每个非文字字符,并将输出写入另一个文件。 通常我会做两种方式:

  • 使用正则表达式结合re.sub 将每个非字母字符替换为空字符串
  • 检查每一行中的每个字符并仅当它在string.lowercase 中时才将其写入输出

但这次的文字是意大利文的神曲(我是意大利人),所以有一些Unicode字符像

èéï

还有一些其他的。我在脚本的第一行写了# -*- coding: utf-8 -*-,但我得到的是,当脚本中写入 Unicode 字符时,Python 不会发出错误信号。

然后我尝试在我的正则表达式中包含 Unicode 字符,例如:

u'\u00AB'

而且它似乎可以工作,但是 Python 在从文件读取输入时,不会像读取它一样重写它读取的内容。例如,某些字符会被转换为平方根符号。

我该怎么办?

【问题讨论】:

  • 看起来 Python 将文件视为 ISO 8859-15 (8859-1) 而不是 UTF-8。您必须弄清楚如何在文件句柄上设置 UTF-8 属性,以便 Python 知道它应该这样对待它。我不知道细节;不过,我确信这是可以做到的。 (请注意,“èéï”映射到 0xC3 0xA8 = U+00E8, 0xC3 0xA9 = U+00E9, 0xC3 0xAF = U+00EF,但如果将字节序列 0xE8, 0xE9, 0xEF 视为 UTF-8,则不是一个有效的序列。这些字节中的每一个都应该跟在 0x80..0xBF 范围内的 3 个字节是有效的 UTF-8。换句话说,不清楚您的文档是 Unicode。
  • 什么是“非文字字符”?
  • @Mike Samuel 我的意思是任何数字符号标点符号。

标签: python unicode


【解决方案1】:

unicodedata.category(unichr) 将返回该代码点的类别。

您可以在 unicode.org 找到类别的描述,但与您相关的是 LNPZ 可能还有 S 组:

Lu    Uppercase_Letter    an uppercase letter
Ll    Lowercase_Letter    a lowercase letter
Lt    Titlecase_Letter    a digraphic character, with first part uppercase
Lm    Modifier_Letter a modifier letter
Lo    Other_Letter    other letters, including syllables and ideographs
...

您可能还想首先规范化您的字符串,以便可以附加到字母的变音符号这样做:

unicodedata.normalize(form, unistr)

返回 Unicode 字符串 unistr 的范式形式。 form 的有效值为“NFC”、“NFKC”、“NFD”和“NFKD”。

把所有这些放在一起:

file_bytes = ...   # However you read your input
file_text = file_bytes.decode('UTF-8')
normalized_text = unicodedata.normalize('NFC', file_text)
allowed_categories = set([
    'Ll', 'Lu', 'Lt', 'Lm', 'Lo',  # Letters
    'Nd', 'Nl',                    # Digits
    'Po', 'Ps', 'Pe', 'Pi', 'Pf',  # Punctuation
    'Zs'                           # Breaking spaces
])
filtered_text = ''.join(
    [ch for ch in normalized_text
     if unicodedata.category(ch) in allowed_categories])
filtered_bytes = filtered_text.encode('UTF-8')  # ready to be written to a file

【讨论】:

  • 完美解决方案,我在发帖前迅速检查了unicodedata,但没有找到任何东西。非常感谢。
【解决方案2】:
import codecs
f = codecs.open('FILENAME', encoding='utf-8')
for line in f:
    print repr(line)
    print line

1。将为您提供 Unicode 格式
2. 将按照您的文件中所写的内容给您。

希望对你有帮助:)

【讨论】:

  • 我仍然得到:UnicodeEncodeError: 'ascii' codec can't encode character u'\xab' in position 0: ordinal not in range(128)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 2013-05-05
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多