У меня есть строка 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, оказывается, имеет способ обработать такие строки, я могу использовать ту функциональность - я не столкнулся ни с чем как этот, как бы то ни было.)
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
При проверке 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)
проверьте код в django.template.defaultfilters.slugify
import unicodedata
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
это то, что вы ищете, затем вы можете сравнить полученную строку с оригиналом
Для того, что, как вы говорите, вы хотите сделать, ваш подход примерно правильный. Если вы работаете под Windows, я бы предложил использовать cp1252
вместо iso-8859-1
. Вы также можете разрешить cp1250
- это позволит охватить страны Восточной Европы, такие как Польша, Чехия, Словакия, Румыния, Словения, Венгрия, Хорватия и т.д., где алфавит основан на латинице. Другие cp125x будут включать турецкий и мальтийский языки ...
Вы также можете рассмотреть возможность транскрипции с кириллицы на латиницу; насколько я знаю, существует несколько систем, одна из которых может быть одобрена ВПС (Всемирным почтовым союзом).
Меня немного заинтриговал ваш комментарий "Наш отдел доставки не хочет заполнять этикетки, например, с китайскими адресами"... три вопроса: (1) вы имеете в виду "адреса в стране X" или "адреса, написанные иероглифами X" (2) не лучше ли вашей системе печатать этикетки? (3) как будет отправлен заказ, если он не пройдет ваш тест?
.Может быть это подойдет, если вы пользователь django?
from django.template.defaultfilters import slugify
def justroman(s):
return len(slugify(s)) == len(s)