当前位置: 首页 > 面试题库 >

拉丁语1至ascii

荀增
2023-03-14
问题内容

我有带重音拉丁字符的unicode字符串,例如

n=unicode('Wikipédia, le projet d’encyclopédie','utf-8')

我想将其转换为普通的ascii,即“ Wikipedia,le projet dencyclopedie”,因此所有急性/重音,塞迪利亚等都应删除

什么是最快的方法,因为需要这样做才能匹配较长的自动完成下拉列表

结论:
作为速度的标准,Lennart的“注册您自己的错误处理程序以进行Unicode编码/解码”可提供最佳效果(请参见Alex的回答),随着拉丁字符越来越多,速度差进一步增加。

这是我使用的转换表,还修改了错误处理程序,因为它需要处理从error.start到error.end的整个未编码char范围

# -*- coding: utf-8 -*-
import codecs

"""
This is more of visual translation also avoiding multiple char translation
e.g. £ may be written as {pound}
"""
latin_dict = {
u"¡": u"!", u"¢": u"c", u"£": u"L", u"¤": u"o", u"¥": u"Y",
u"¦": u"|", u"§": u"S", u"¨": u"`", u"©": u"c", u"ª": u"a",
u"«": u"<<", u"¬": u"-", u"­": u"-", u"®": u"R", u"¯": u"-",
u"°": u"o", u"±": u"+-", u"²": u"2", u"³": u"3", u"´": u"'",
u"µ": u"u", u"¶": u"P", u"·": u".", u"¸": u",", u"¹": u"1",
u"º": u"o", u"»": u">>", u"¼": u"1/4", u"½": u"1/2", u"¾": u"3/4",
u"¿": u"?", u"À": u"A", u"Á": u"A", u"Â": u"A", u"Ã": u"A",
u"Ä": u"A", u"Å": u"A", u"Æ": u"Ae", u"Ç": u"C", u"È": u"E",
u"É": u"E", u"Ê": u"E", u"Ë": u"E", u"Ì": u"I", u"Í": u"I",
u"Î": u"I", u"Ï": u"I", u"Ð": u"D", u"Ñ": u"N", u"Ò": u"O",
u"Ó": u"O", u"Ô": u"O", u"Õ": u"O", u"Ö": u"O", u"×": u"*",
u"Ø": u"O", u"Ù": u"U", u"Ú": u"U", u"Û": u"U", u"Ü": u"U",
u"Ý": u"Y", u"Þ": u"p", u"ß": u"b", u"à": u"a", u"á": u"a",
u"â": u"a", u"ã": u"a", u"ä": u"a", u"å": u"a", u"æ": u"ae",
u"ç": u"c", u"è": u"e", u"é": u"e", u"ê": u"e", u"ë": u"e",
u"ì": u"i", u"í": u"i", u"î": u"i", u"ï": u"i", u"ð": u"d",
u"ñ": u"n", u"ò": u"o", u"ó": u"o", u"ô": u"o", u"õ": u"o",
u"ö": u"o", u"÷": u"/", u"ø": u"o", u"ù": u"u", u"ú": u"u",
u"û": u"u", u"ü": u"u", u"ý": u"y", u"þ": u"p", u"ÿ": u"y", 
u"’":u"'"}

def latin2ascii(error):
    """
    error is  protion of text from start to end, we just convert first
    hence return error.start+1 instead of error.end
    """
    return latin_dict[error.object[error.start]], error.start+1

codecs.register_error('latin2ascii', latin2ascii)

if __name__ == "__main__":
    x = u"¼ éíñ§ÐÌëÑ » ¼ ö ® © ’"
    print x
    print x.encode('ascii', 'latin2ascii')

我为什么回来error.start + 1

返回的错误对象可以是多个字符,我们仅转换其中的第一个,例如,如果我添加print error.start, error.end到错误处理程序,则输出为

¼ éíñ§ÐÌëÑ » ¼ ö ® © ’
0 1
2 10
3 10
4 10
5 10
6 10
7 10
8 10
9 10
11 12
13 14
15 16
17 18
19 20
21 22
1/4 einSDIeN >> 1/4 o R c '

因此在第二行中,我们从2-10获得字符,但我们仅转换2nd,因此如果返回error,则返回3作为继续点。end输出为

¼ éíñ§ÐÌëÑ » ¼ ö ® © ’
0 1
2 10
11 12
13 14
15 16
17 18
19 20
21 22
1/4 e >> 1/4 o R c '

如我们所见,2-10部分已被单个字符替换。当然,一次编码整个范围并返回error.end会更快,但是出于演示目的,我将其简化了。

有关更多详细信息,请参见http://docs.python.org/library/codecs.html#codecs.register_error


问题答案:

因此,这是三种方法,或多或少都由其他答案给出或建议:

# -*- coding: utf-8 -*-
import codecs
import unicodedata

x = u"Wikipédia, le projet d’encyclopédie"

xtd = {ord(u'’'): u"'", ord(u'é'): u'e', }

def asciify(error):
    return xtd[ord(error.object[error.start])], error.end

codecs.register_error('asciify', asciify)

def ae():
  return x.encode('ascii', 'asciify')

def ud():
  return unicodedata.normalize('NFKD', x).encode('ASCII', 'ignore')

def tr():
  return x.translate(xtd)

if __name__ == '__main__':
  print 'or:', x
  print 'ae:', ae()
  print 'ud:', ud()
  print 'tr:', tr()

以main身份运行,它发出:

or: Wikipédia, le projet d’encyclopédie
ae: Wikipedia, le projet d'encyclopedie
ud: Wikipedia, le projet dencyclopedie
tr: Wikipedia, le projet d'encyclopedie

清楚地表明,基于unicodedata的方法确实具有不需要翻译图的便利,xtd但是不能以自动方式正确翻译所有字符(它适用于重音字母,但不适用于反撇号),因此它还需要一些辅助步骤来显式地处理这些问题(毫无疑问,现在是它的主体了)。

性能也很有趣。在我的装有Mac OS X 10.5和系统Python 2.5的笔记本电脑上,可重复的是:

$ python -mtimeit -s'import a' 'a.ae()'
100000 loops, best of 3: 7.5 usec per loop
$ python -mtimeit -s'import a' 'a.ud()'
100000 loops, best of 3: 3.66 usec per loop
$ python -mtimeit -s'import a' 'a.tr()'
10000 loops, best of 3: 21.4 usec per loop

translate出奇地慢(相对于其他方法)。我认为问题在于,对于translate案例中的每个字符(大多数不存在)都只检查了dict
,而对于asciify方法中存在的仅有的几个字符,则进行了调查。

因此,为了完整起见,这里使用“优化unicodedata”方法:

specstd = {ord(u'’'): u"'", }
def specials(error):
  return specstd.get(ord(error.object[error.start]), u''), error.end
codecs.register_error('specials', specials)

def bu():
  return unicodedata.normalize('NFKD', x).encode('ASCII', 'specials')

这给出了正确的输出,但是:

$ python -mtimeit -s'import a' 'a.bu()'
100000 loops, best of 3: 10.7 usec per loop

…速度不再那么好了。因此,如果速度很重要,那么做出完整的xtd翻译命令并使用该asciify方法无疑是值得的。当每次翻译多花几微秒的时间没什么大不了的时候,您可能bu只是为了方便而考虑使用此方法(只需要一个翻译字典即可,希望有一些特殊的字符无法与基础unicodedata想法正确地翻译)。



 类似资料:
  • 问题内容: 我正在尝试将西里尔字母的单词写成拉丁语,以便可以在url中使用它们。我使用的是icu4j音译器,但它仍然会给出如下奇怪的字符: Vilaândimaa 。它应该更像 viljandimaa 。当我复制该网址时,这些字母会变成%..没用的东西。 有人知道如何使用icu4j将西里尔字母转化为az吗? 更新 已经无法回答自己,但是发现这个问题非常有用:将符号,重音字母转换为英文字母 问题答案

  • 谷歌Web字体上的一些字体支持多个“字符集”。问题是,如果我使用的web字体只提供“拉丁”字形,用户将页面翻译成不支持字形的语言时,会清楚地注意到混乱的文本。 我希望我的网页字体支持最流行的语言在世界上除了英语,例如,西班牙语,德语,法语等。 出于这个目的,我想知道,“拉丁”和“拉丁扩展”到底是针对哪种语言的。 我想答案应该是这样的:

  • 我尝试使用字符集latin1排序规则latin1\u general\u ci将字符集ISO-8859-15的字符串存储在MySQL字段中。 似乎这两者都不完全兼容。我无法保存正确的€-符号。 有人能告诉我ISO-8859-15的正确吗?

  • 问题内容: 请帮我! 我正在将多行文本文件转换为猪拉丁文。 示例:Pig的拉丁语翻译:这是一个示例。应该是:Histay siay naay xampleeay。 我需要将标点符号留在原处(大多数情况下是句子的结尾)。我还需要任何以原始字母大写字母开头,以猪拉丁字母大写字母开头的单词,以及其余的字母小写。 这是我的代码: 我的文本文件是: 程序返回: 我如何让他们按照他们所在的行打印?另外,我该如

  • 问题内容: 我有一个树形结构,其中的关键字可能包含一些拉丁字符。我有一个遍历树上所有叶子并在特定条件下将每个关键字添加到列表的函数。 这是我将这些关键字添加到列表中的代码: 如果在这种情况下的关键字是,那么我的输出是: 看来打印功能可以正确显示拉丁字符,但是当我将其添加到列表中时,它就会被解码。 我该如何更改?我需要能够使用标准拉丁字符而不是它们的解码版本来打印列表。 问题答案: 您没有unico

  • 我正在尝试将我的googlemaps v2函数移植到v3。 但不知怎的,我陷入了一个奇怪的错误,我找不到我做错了什么。 错误:未捕获的InvalidValueError: setPoint: not a latLng or latLngLitald: in属性lat: not a数字{main, adSense,几何,僵尸}. js: 25 这里是我的地图初始化: 这是我错误的部分: 编辑:dra