Как я могу проверить, содержит ли Python unicode строка незападные буквы?

У меня есть строка Unicode Python. Я хочу удостовериться, что это только содержит буквы от Романского алфавита (Через Z), а также обычно обозначает буквами находимый в европейских алфавитах, таких как ß, ü, ø, é, à, и î. Это не должно содержать символы от других алфавитов (китайский язык, японский язык, корейский, арабский, кириллица, иврит, и т.д.). Что лучший способ состоит в том, чтобы пойти о выполнении этого?

В настоящее время я использую этот бит кода, но я не знаю, является ли это лучший способ:

def only_roman_chars(s):
    try:
        s.encode("iso-8859-1")
        return True
    except UnicodeDecodeError:
        return False

(Я использую Python 2.5. Я также делаю это в Django, поэтому если платформа Django, оказывается, имеет способ обработать такие строки, я могу использовать ту функциональность - я не столкнулся ни с чем как этот, как бы то ни было.)

25
задан mipadi 22 June 2010 в 16:18
поделиться

5 ответов

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
34
ответ дан 28 November 2019 в 18:21
поделиться

При проверке ISO-8559-1 будут пропущены разумные западные символы, такие как «œ» и «€». Решение зависит от того, как вы определяете «западный» и как вы хотите обрабатывать небуквенные символы. Вот один из подходов:

import unicodedata

def is_permitted_char(char):
    cat = unicodedata.category(char)[0]
    if cat == 'L': # Letter
        return 'LATIN' in unicodedata.name(char, '').split()
    elif cat == 'N': # Number
        # Only DIGIT ZERO - DIGIT NINE are allowed
        return '0' <= char <= '9'
    elif cat in ('S', 'P', 'Z'): # Symbol, Punctuation, or Space
        return True
    else:
        return False

def is_valid(text):
    return all(is_permitted_char(c) for c in text)
1
ответ дан 28 November 2019 в 18:21
поделиться

проверьте код в django.template.defaultfilters.slugify

import unicodedata
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')

это то, что вы ищете, затем вы можете сравнить полученную строку с оригиналом

0
ответ дан 28 November 2019 в 18:21
поделиться

Для того, что, как вы говорите, вы хотите сделать, ваш подход примерно правильный. Если вы работаете под Windows, я бы предложил использовать cp1252 вместо iso-8859-1. Вы также можете разрешить cp1250 - это позволит охватить страны Восточной Европы, такие как Польша, Чехия, Словакия, Румыния, Словения, Венгрия, Хорватия и т.д., где алфавит основан на латинице. Другие cp125x будут включать турецкий и мальтийский языки ...

Вы также можете рассмотреть возможность транскрипции с кириллицы на латиницу; насколько я знаю, существует несколько систем, одна из которых может быть одобрена ВПС (Всемирным почтовым союзом).

Меня немного заинтриговал ваш комментарий "Наш отдел доставки не хочет заполнять этикетки, например, с китайскими адресами"... три вопроса: (1) вы имеете в виду "адреса в стране X" или "адреса, написанные иероглифами X" (2) не лучше ли вашей системе печатать этикетки? (3) как будет отправлен заказ, если он не пройдет ваш тест?

.
1
ответ дан 28 November 2019 в 18:21
поделиться

Может быть это подойдет, если вы пользователь django?

from django.template.defaultfilters import slugify 

def justroman(s):
  return len(slugify(s)) == len(s)
0
ответ дан 28 November 2019 в 18:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: