【问题标题】:Remove characters with accents from string [duplicate]从字符串中删除带有重音符号的字符[重复]
【发布时间】:2014-06-01 14:11:15
【问题描述】:

我需要处理一个损坏的数据库,其中一次存储带有重音符号的名称,一次存储非 ASCII 字符的名称。特别是我有以下两条记录:

record_1 = u'Tim Münster'  
record_2 = u'Tim Mnster'

有没有可能找到这样的重复记录?

【问题讨论】:

  • 这似乎微不足道。您可以简单地使用 "".join([x for x in s if ord(x)<128]) 删除非 ascii 字符(hacky,但有效),并使用 set 操作检查重复项。你被困在哪里了?
  • @goncalopp 看起来很像一个答案!为什么不将其作为一个发布?
  • @TomFenech 我想成为他想要的东西似乎太容易了
  • 谢谢,我喜欢这个 hacky 解决方案。将尝试并最终发布更新,如果它没有完全工作。

标签: python unicode duplicates


【解决方案1】:

您可以通过与re.sub(r'[^a-zA-Z ]', '', record_1) 进行比较来删除错误的重复项。

【讨论】:

    【解决方案2】:

    你可以删除非ASCII字符

    def remove_nonascii(s):
        return "".join(x for x in s if ord(x)<128)
    

    要检查重复项,只需使用sets:

    records= set([u'Tim Mnster'])
    duplicates_to_check= [u'Tim Münster']
    for possible_duplicate in duplicates_to_check:
        if remove_nonascii( possible_duplicate ) in records:
            print possible_duplicate, "is a duplicate"
    

    【讨论】:

    • 您的join 中不需要[ ]
    • @TomFenech 确实,我仍然不习惯在日常情况下使用生成器表达式。列表推导 might be slightly faster, though
    • @TomFenech 实际上是str.join is both faster and memory-efficient 与列表一起使用时。
    • @Aशwiniचhaudhary 我从来不知道。那时我可能也会改变我的答案。谢谢!
    • @TomFenech 如果字符串不是很大,那么差异并不重要,我确实发现str.find 一起使用时更具可读性。
    【解决方案3】:

    查找重复记录-

    我会这样做:

    1) 从字符串中删除带重音的字符。

    import unicodedata
    
    def remove_accents(input_str):
        nkfd_form = unicodedata.normalize('NFKD', input_str)
        only_ascii = nkfd_form.encode('ASCII', 'ignore')
        return only_ascii
    

    2) 检查去掉重音的字符串 (record_1) 是否等于 record_2(使用 Levenshtein 距离算法),模糊匹配。

    from nltk import metrics, stem, tokenize
    
    def normalize(s):
        words = tokenize.wordpunct_tokenize(s.lower().strip())
        return ' '.join([stemmer.stem(w) for w in words])
    
    def fuzzy_match(s1, s2, max_dist=2):
        return metrics.edit_distance(normalize(s1), normalize(s2)) <= max_dist
    

    【讨论】:

      【解决方案4】:

      您可以使用string 模块中的ascii_letterswhitespace

      import string
      def ascii_or_space(s):
          return "".join(c for c in s if c in string.ascii_letters + string.whitespace)
      
      ascii_or_space(record_1) == record_2
      True
      

      【讨论】:

        猜你喜欢
        • 2012-01-21
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2019-03-31
        • 1970-01-01
        • 2014-12-11
        相关资源
        最近更新 更多