【Python CheckiO 题解】Remove Accents


CheckiO 是面向初学者和高级程序员的编码游戏,使用 Python 和 JavaScript 解决棘手的挑战和有趣的任务,从而提高你的编码技能,本博客主要记录自己用 Python 在闯关时的做题思路和实现代码,同时也学习学习其他大神写的代码。

CheckiO 官网:https://checkio.org/

我的 CheckiO 主页:https://py.checkio.org/user/TRHX/

CheckiO 题解系列专栏:https://itrhx.blog.csdn.net/category_9536424.html

CheckiO 所有题解源代码:https://github.com/TRHX/Python-CheckiO-Exercise


题目描述

【Remove Accents】:给定一个 Unicode 字符串,去除其中的重音符号,é:带重音的字母,e:不带重音的字母,̀ :独立的重音符号。

【链接】https://py.checkio.org/mission/remove-accents/

【输入】:字符串(Unicode)

【输出】:无重音的 Unicode 字符串

【前提】:0≤|input|≤40

【范例】

checkio(u"préfèrent") == u"preferent"
checkio(u"loài trăn lớn") == u"loai tran lon"

解题思路

了解这些特殊字符,比如:Spicy Jalapeño 使用的是拉丁字母“n”紧跟着一个“~”组合而成的字符(U+0303),也就是 Spicy Jalapen\u0303o

利用 unicodedata 模块,normalize() 方法将字符串进行分解,利用 combining() 方法对字符做检查,判断它是否为一个组合型字符(包含重音字符等特殊字符),如果不是组合型字符,则将其组成一个新的字符串。

知识扩展

unicodedata.normalize(form, unistr) 方法:

把一串 Unicode 字符串转换为普通格式的字符串,具体格式(form)支持 NFC、NFKC、NFD 和 NFKD 格式。

一些文本元素既可以使用静态的预先组合好的形式,也可使用动态组合的形式。Unicode 字符的不同表示序列被认为是等价的。如果两个或多个序列被认为是等价的,Unicode 标准不规定哪一种特定的序列是正确的,而认为每一个序列只不过与其它序列等价。如果需要一种单一的表示方式,可以使用一种规范化的 Unicode 文本形式来减少不想要区别。Unicode 标准定义了四种规范化形式: Normalization Form D (NFD),Normalization Form KD (NFKD),Normalization Form C (NFC),和Normalization Form KC (NFKC)。

NFD 和 NFKD 将可能的字符进行分解,而 NFC 和 NFKC 将可能的字符进行组合。

unicodedata 模块文档:https://docs.python.org/zh-cn/3.7/library/unicodedata.html

以下举例说明不同格式(form)的区别:

例(NFC):

import unicodedata

in_string = u"préfèrent"
for c in unicodedata.normalize('NFC', in_string):
    print(c)

输出结果

p
r
é
f
è
r
e
n
t

例(NFD):

import unicodedata

in_string = u"préfèrent"
for c in unicodedata.normalize('NFD', in_string):
    print(c)

输出结果:

p
r
e
́
f
e
̀
r
e
n
t

代码实现

import unicodedata


def checkio(in_string):
    # remove accents
    return ''.join(i for i in unicodedata.normalize('NFD', in_string) if not unicodedata.combining(i))


    # These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio(u"préfèrent") == u"preferent"
    assert checkio(u"loài trăn lớn") == u"loai tran lon"
    print('Done')

大神解答

大神解答 NO.1

from unicodedata import category, normalize

def checkio(string):
    return ''.join(c for c in normalize('NFKD', string) if category(c) != 'Mn')

大神解答 NO.2

from unicodedata import normalize, combining as accent
from functools import partial as curry
from itertools import filterfalse as removeif

take_apart = curry(normalize, "NFD")
remove_accents = curry(removeif, accent)
make_str = ''.join

def compose(*funcs):
    def composition(x):
        for func in funcs:
            x = func(x)
        return x
    return composition

checkio = compose(take_apart, remove_accents, make_str)

大神解答 NO.3

from unicodedata import category as cat, name
import re

def checkio(s):
    return ''.join(eval("'{}'.{}er()".format(                 #  evaluator
        *re.findall('LETTER (.?)', name(c)) or c,             #  "letters"
        'upp' if cat(c) == 'Lu' else 'low'))                  #  letter case
        for c in filter(lambda c: cat(c)[0] in 'PuZzLeS', s)) #  letter generator

大神解答 NO.4

from unicodedata import normalize

def checkio(s):
   return ''.join(c for c in normalize('NFD', s) if c not in u"̨̧̛̣̱̮̉̇̊̄̃̑̂̏̋̈̌̆̀́")
发布了149 篇原创文章 · 获赞 518 · 访问量 46万+

猜你喜欢

转载自blog.csdn.net/qq_36759224/article/details/103534788
今日推荐