Comment puis-je vérifier si un Python unicode chaîne contient des non-Ouest de lettres?
J'ai un Python chaîne Unicode. Je veux m'assurer qu'il ne contient que des lettres de l'alphabet Romain (A à Z), ainsi que des lettres couramment trouvés dans les alphabets Européens, tels que le ß, ü, ø, é, à, et î. Il devrait pas contenir des caractères à partir d'autres alphabets (Chinois, Japonais, coréen, arabe, Cyrillique, hébreu, etc.). Quelle est la meilleure façon de faire cela?
Actuellement j'utilise ce bout de code, mais je ne sais pas si c'est la meilleure façon:
def only_roman_chars(s):
try:
s.encode("iso-8859-1")
return True
except UnicodeDecodeError:
return False
(Je suis à l'aide de Python 2.5. Je fais également présent dans Django, donc si le framework Django arrive à avoir un moyen de gérer ces chaînes, je peux utiliser cette fonctionnalité -- je n'ai pas rencontré quelque chose comme ça, cependant.)
- Quel est votre but dans le filtrage de ces personnages? Je ne peux pas penser à une bonne raison de le faire ce qui n'est pas un symptôme de quelque chose de mal, d'ailleurs dans le code.
- Le filtrage des adresses postales. Notre service d'expédition ne voulez pas avoir à remplir des étiquettes avec, par exemple, le Chinois des adresses.
- Ne pouvez-vous pas de filtre sur le pays à la place alors? (sinon, question intéressante +1)
- Pas vraiment. Quelqu'un pourrait sélectionnez "Chine" et encore entrer une adresse appropriée, par exemple.
- github.com/EliFinkelshteyn/alphabet-detector/blob/master/...
Vous devez vous connecter pour publier un commentaire.
uchr.isalpha()
au lieu deunicodedata.category(uchr).startswith('L')
. Envisagez d'utiliser un ensemble construit au module de temps de chargement:okletters = set(unichr(i) for i in xrange(sys.maxunicode+1) if unicodedata.name(unichr(i), "").startswith('LATIN '))
c'est à dire utiliseruchr in okletters
au lieu de'LATIN' in unicodedata.name(uchr)
is_latin
fonction, une sous-classe dedefaultdict
de façon appropriée primordial__missing__
serait également s'avérer une bonne solution.Le haut de répondre à cette par @tzot est grande, mais IMO il devrait vraiment être une bibliothèque de ce qui fonctionne pour tous les scripts. Donc, j'en ai fait une (fortement basée sur la réponse).
et ensuite l'utiliser directement:
Aussi, quelques méthodes pratiques pour les langues principales:
Pour ce que vous dites que vous voulez faire, votre approche est sujet de droit. Si vous êtes en cours d'exécution sur Windows, je vous conseille d'utiliser
cp1252
au lieu deiso-8859-1
. Vous pouvez également permettrecp1250
ainsi -- ce serait ramasser les pays d'europe orientale comme la Pologne, la République tchèque, la Slovaquie, la Roumanie, la Slovénie, la Hongrie, la Croatie, etc, où l'alphabet est latine. D'autres cp125x comprendrait le turc et le Maltais ...Vous pouvez également envisager de transcription de l'alphabet Cyrillique au Latin; autant que je sache, il existe plusieurs systèmes, dont l'un peut être endossé par l'UPU (Union Postale Universelle).
Je suis un peu intrigué par votre commentaire "Notre service d'expédition ne voulez pas avoir à remplir des étiquettes avec, par exemple, le Chinois des adresses" ... trois questions: (1) voulez-vous dire par "les adresses dans le pays X" ou "les adresses écrites dans X-ese caractères" (2) ne serait-il pas mieux pour votre système d'imprimer les étiquettes? (3) quel est l'ordre d'obtenir expédiés si elle ne parvient pas votre test?
La vérification de l'ISO-8559-1 serait manquer raisonnable de l'Ouest de caractères comme 'œ' et '€'. La solution dépend de comment vous définissez "de l'Ouest", et la façon dont vous voulez gérer les non-lettres. Voici une approche:
return unicodedata.name(char, '').startswith('LATIN ')
devrait suffire (2) memoising les résultats de la fonction pourrait être une bonne idée, qui pourrait être améliorée par le préchargement les suspects habituels [-A-Za-z0-9,./ '] etc ... dans la note (3) symbole/la ponctuation est assez large (4) si la catégorie de l'Espace être remplacé par '\x20'?vérifier le code dans
django.template.defaultfilters.slugify
est ce que vous cherchez, vous pouvez alors comparer la chaîne résultante à l'original
Peut-être cela va faire si vous êtes un django d'utilisateur?