如何检查Python unicode字符串是否包含非西方字母?

mip*_*adi 26 python django unicode

我有一个Python Unicode字符串.我想确保它只包含罗马字母(A到Z)中的字母,以及欧洲字母表中常见的字母,例如ß,ü,ø,é,à和î.它应该包含其他字母(中国,日本,韩语,阿拉伯语,俄语,希伯来语等)的字符.这样做的最佳方法是什么?

目前我正在使用这段代码,但我不知道它是否是最好的方法:

def only_roman_chars(s):
    try:
        s.encode("iso-8859-1")
        return True
    except UnicodeDecodeError:
        return False
Run Code Online (Sandbox Code Playgroud)

(我正在使用Python 2.5.我也在Django中这样做,所以如果Django框架碰巧有办法处理这样的字符串,我可以使用该功能 - 但是我没有遇到过类似的东西.)

tzo*_*zot 34

import unicodedata as ud

latin_letters= {}

def is_latin(uchr):
    try: return latin_letters[uchr]
    except KeyError:
         return latin_letters.setdefault(uchr, 'LATIN' in ud.name(uchr))

def only_roman_chars(unistr):
    return all(is_latin(uchr)
           for uchr in unistr
           if uchr.isalpha()) # isalpha suggested by John Machin

>>> only_roman_chars(u"???????? means greek")
False
>>> only_roman_chars(u"frappé")
True
>>> only_roman_chars(u"hôtel lœwe")
True
>>> only_roman_chars(u"123 ångstrom ð áß")
True
>>> only_roman_chars(u"russian: ????")
False
Run Code Online (Sandbox Code Playgroud)

  • 考虑`uchr.isalpha()`而不是`unicodedata.category(uchr).startswith('L')`.考虑使用在模块加载时构造的集合:`okletters = set(unichr(i)for i in xrange(sys.maxunicode + 1)if unicodedata.name(unichr(i),"").startswith('LATIN') )`即在unicodedata.name(uchr)中使用`uchr in okletters`而不是''LATIN' (2认同)

Eli*_*Eli 28

@tzot的最佳答案很棒,但IMO应该有一个适用于所有脚本的库.所以,我做了一个(很大程度上基于那个答案).

pip install alphabet-detector
Run Code Online (Sandbox Code Playgroud)

然后直接使用它:

from alphabet_detector import AlphabetDetector
ad = AlphabetDetector()

ad.only_alphabet_chars(u"???????? means greek", "LATIN") #False
ad.only_alphabet_chars(u"????????", "GREEK") #True
ad.only_alphabet_chars(u'????? ????', 'ARABIC')
ad.only_alphabet_chars(u'????', 'HEBREW')
ad.only_alphabet_chars(u"frappé", "LATIN") #True
ad.only_alphabet_chars(u"hôtel lœwe 67", "LATIN") #True
ad.only_alphabet_chars(u"det forårsaker første", "LATIN") #True
ad.only_alphabet_chars(u"Cyrillic and ?????????????", "LATIN") #False
ad.only_alphabet_chars(u"?????????????", "CYRILLIC") #True
Run Code Online (Sandbox Code Playgroud)

此外,主要语言的一些便利方法:

ad.is_cyrillic(u"?????") #True  
ad.is_latin(u"howdy") #True
ad.is_cjk(u"hi") #False
ad.is_cjk(u'??') #True
Run Code Online (Sandbox Code Playgroud)