【问题标题】:Python: How to remove the majority of special unicode chars but leave accents and mutated vowels intact?Python:如何删除大部分特殊的 unicode 字符,但保留重音和变异元音?
【发布时间】:2023-03-12 15:59:01
【问题描述】:

我正在用 Python 从网页中抓取文本。

文本包含各种特殊的 unicode 字符,例如心形、表情符号和其他狂野的东西。

通过使用content.encode('ascii', 'ignore'),我可以将所有内容转换为 ASCII,但这意味着所有重音字符和变异元音(例如 'ä' 或 'ß' )也会消失。

如何保持“ä”或“é”等“正常”字符完好无损,但可以删除所有其他内容?

(我必须承认我是 Python 的新手,我从来没有真正了解字符编码背后的所有魔力)。

【问题讨论】:

  • 您能否提供一个示例输入和预期输出,并展示您迄今为止尝试过的内容。
  • 为什么不能使用unicode?​​span>
  • content.encode('latin1','ignore') 将保留常见的西欧重音字符。你仍然会失去俄语、日语、中文等。
  • @JörgF。你不能。编辑您的问题,而不是创建难以辨认的 cmets。

标签: python unicode non-ascii-characters


【解决方案1】:

您的问题并不完全清楚您在“好”和“坏”角色之间划清界限,但您可能还不知道。 Unicode 包含许多不同种类的字符,您可能不知道其多样性。

Unicode 为每个字符分配一个category,例如“字母,小写”或“标点符号,最后引号”或“符号,其他”。 Python 的 std-lib 模块 unicodedata 让您可以方便地访问这些信息:

>>> import unicodedata as ud
>>> ud.category('ä')
'Ll'
>>> ud.category('?')
'So'

从您的示例看来,您认为 letters 是好的,而 symbols 是不好的。 但你也必须解决剩下的问题。 您可能还想保留空格(“分隔符”)和标点符号。 您可能也需要这些标记,因为它们包括combining characters

【讨论】:

    【解决方案2】:

    几个步骤:

    您应该使用unicodedata.normalize('NFC', my_text) 规范化unicode。不是真的在这个问题上,但你们必须有一个共同点,让我们有相同的字符有相同的编码。

    然后你应该检查每个字符,看看你是否允许:

    new_text = []
    for c in my_normalized_text:
        if ord(c) < 128:
            # this is optional, it add ascii character as they are
            # possibly you want to tokenize (see later, how we replace punctuation)
            new_text.append(c)
            continue
        cat = unicodedata.category(c)
        if cat in {'Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nd'}:
            new_text.append(c)
        elif cat in {'Mc', 'Pc', 'Pd', 'Ps', 'Pe', 'Pi', 'Of', 'Po', 'Zs', 'Zl', 'Zp'}:
            # this tokenize
            new_text.append(' ')
        # else: do not append. You may still append ' ' and remove above check.
    

    您应该根据您的下一个处理方法进行调整:参见Python Unicode HOWTO和链接页面Unicode character categories

    【讨论】:

      【解决方案3】:

      嗯,我终于用这个了:

          # create translation map for non-bmp charactes
          non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)
      
          # strip unwanted unicode images
          question = question.translate(non_bmp_map)
      
          # convert to latin-1 to remove all stupid unicode characters
          # you may want to adapt this to your personal needs
          #
          # for some strange reason I have to first transform the string to bytes with latin-1
          # encoding and then do the reverse transform from bytes to string with latin-1 encoding as
          # well... maybe has to be revised later
          bQuestion = question.encode('latin-1', 'ignore')
          question = bQuestion.decode('latin-1', 'ignore')
      

      感谢所有回答的人

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-31
        • 2014-02-05
        • 2014-03-16
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        • 2016-06-26
        • 2023-03-03
        相关资源
        最近更新 更多