J'ai récemment rencontré une exigence au travail, qui nécessite de détecter si un champ contient des mots rares et des caractères illégaux tels que ~!@#$%^&*. Je l'ai résolu en recherchant des informations sur Internet. Je vais maintenant partager le processus de solution et un exemple de code avec tous ceux qui en ont besoin peuvent s'y référer. Jetons un coup d'œil ci-dessous.
Solution
La première chose qui me vient à l'esprit est d'utiliser les expressions régulières de Python pour faire correspondre les caractères illégaux, puis trouver les enregistrements illégaux. Cependant, les idéaux sont toujours pleins, mais la réalité est cruelle. Au cours du processus d'implémentation, j'ai découvert que je manquais de connaissances sur le codage des caractères et la représentation interne des chaînes de Python. Durant cette période, j'ai traversé de nombreux pièges, et même s'il restait finalement quelques ambiguïtés, j'ai finalement eu une compréhension globale claire. Enregistrez votre expérience ici pour éviter de tomber au même endroit à l'avenir.
L'environnement de test suivant est l'environnement Python 2.7.8 fourni avec ArcGIS 10.3. Il n'y a aucune garantie que d'autres environnements Python conviendront également.
Expression régulière Python
La fonction régulière en python est fournie par la bibliothèque de fonctions re intégrée, qui utilise principalement 3 fonctions. re.compile()
fournit des expressions régulières réutilisables, et les fonctions match()
et search()
renvoient des résultats correspondants. La différence entre les deux est la suivante : match()
commence la correspondance à partir de la position spécifiée et search()
recherche en arrière à partir de la position spécifiée. jusqu'à ce qu'une chaîne correspondante soit trouvée. Par exemple, dans le code suivant, match_result
commence la correspondance à partir du premier caractère f et renvoie une valeur nulle si la correspondance échoue ; search_result
recherche en arrière à partir de f jusqu'à ce que le premier caractère correspondant a soit trouvé, puis utilise le groupe. () fonction Le résultat de la correspondance de sortie est le caractère a.
import re pattern = re.compile('[abc]') match_result = pattern.match('fabc') if match_result: print match_result.group() search_result = pattern.search('fabc') if search_result: print search_result.group()
L'implémentation ci-dessus nécessite d'abord de compiler un modèle, puis de le faire correspondre. En fait, nous pouvons utiliser directement la fonction re.match(pattern, string)
pour obtenir la même fonctionnalité. Cependant, la méthode de correspondance directe n'est pas aussi flexible que la compilation puis la correspondance. Tout d'abord, les expressions régulières ne peuvent pas être réutilisées si une grande quantité de données correspond au même modèle, cela signifie qu'une compilation interne est nécessaire à chaque fois. entraînant une perte de performances ; de plus, la fonction re.match()
Ce n'est pas aussi puissant que pattern.match()
, qui peut spécifier la position à partir de laquelle commencer la correspondance.
Problèmes d'encodage
Après avoir compris les fonctions de base des expressions régulières Python, il ne reste plus qu'à trouver une expression régulière appropriée pour correspondre à des expressions régulières rares. mots et caractères illégaux. Les caractères illégaux sont très simples. Vous pouvez les faire correspondre en utilisant le modèle suivant :
pattern = re.compile(r'[~!@#$%^&* ]')
Cependant, la correspondance de caractères inhabituels me laisse vraiment perplexe. La première est la définition des mots rares. Quels types de mots sont considérés comme rares ? Après consultation avec le chef de projet, il a été déterminé que les caractères non GB2312 sont des caractères rares. La question suivante est : comment faire correspondre les caractères GB2312 ?
Après requête, la plage de GB2312 est [xA1-xF7][xA1-xFE]
et la plage de la zone des caractères chinois est [xB0-xF7][xA1-xFE]
. Par conséquent, l'expression après avoir ajouté la correspondance de mots rares est :
pattern = re.compile(r'[~!@#$%^&* ]|[^\xA1-\xF7][^\xA1-\xFE]')
Le problème semble être résolu logiquement, mais je suis encore trop simple et trop naïf. Étant donné que les chaînes à juger sont toutes lues à partir de fichiers de couches, arcpy encode judicieusement les caractères lus au format Unicode. Par conséquent, je dois connaître la plage de codage du jeu de caractères GB2312 en Unicode. Mais la réalité est que la distribution du jeu de caractères GB2312 en Unicode n'est pas continue et que l'utilisation d'expressions régulières pour représenter cette plage doit être très compliquée. L’idée d’utiliser des expressions régulières pour faire correspondre des mots rares semble être dans une impasse.
Solution
Étant donné que la chaîne fournie est au format Unicode, puis-je la convertir en GB2312 puis la faire correspondre ? En fait, ce n'est pas possible, car le jeu de caractères Unicode est beaucoup plus grand que le jeu de caractères GB2312, donc GB2312 => unicode
peut toujours être réalisé, mais à l'inverse unicode => GB2312
ne peut pas nécessairement réussir.
Cela m'a soudainement donné une autre idée. En supposant que la unicode => GB2312
conversion d'une chaîne échoue, cela signifie-t-il qu'elle n'appartient pas au jeu de caractères GB2312 ? J'ai donc utilisé la fonction unicode_string.encode('GB2312')
pour essayer de convertir la chaîne, en interceptant l'exception UnicodeEncodeError pour identifier les mots rares.
Le code final est le suivant :
import re def is_rare_name(string): pattern = re.compile(u"[~!@#$%^&* ]") match = pattern.search(string) if match: return True try: string.encode("gb2312") except UnicodeEncodeError: return True return False
Résumé
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!