Lösungsideen
Das erste, was mir in den Sinn kommt, ist, die regulären Ausdrücke von Python zu verwenden, um illegale Zeichen abzugleichen und dann illegale Datensätze zu finden. Allerdings sind die Ideale immer voll, aber die Realität ist grausam. Während des Implementierungsprozesses stellte ich fest, dass mir Kenntnisse über die Zeichenkodierung und die interne String-Darstellung von Python fehlten. In dieser Zeit bin ich auf viele Fallstricke gestoßen, und obwohl es am Ende immer noch einige Unklarheiten gab, hatte ich schließlich ein klares Gesamtverständnis. Notieren Sie hier Ihre Erfahrungen, um in Zukunft nicht wieder an die gleiche Stelle zu fallen.
Die folgende Testumgebung ist die Python 2.7.8-Umgebung, die mit ArcGIS 10.3 geliefert wird. Es gibt keine Garantie, dass auch andere Python-Umgebungen anwendbar sind.
regulärer Python-Ausdruck
Die reguläre Funktion in Python wird von der integrierten Re-Funktionsbibliothek bereitgestellt, die hauptsächlich drei Funktionen verwendet. re.compile()
stellt wiederverwendbare reguläre Ausdrücke bereit, und die Funktionen match()
und search()
geben Übereinstimmungsergebnisse zurück. Der Unterschied zwischen den beiden besteht darin, dass match()
den Abgleich an der angegebenen Position beginnt und search()
die Suche ab der angegebenen Position rückwärts durchführt. bis eine passende Zeichenfolge gefunden wird. Im folgenden Code beginnt match_result
beispielsweise mit dem Abgleich ab dem ersten Zeichen f und gibt einen Nullwert zurück, wenn der Abgleich fehlschlägt. search_result
sucht rückwärts von f, bis das erste übereinstimmende Zeichen a gefunden wird, und verwendet dann die Gruppe ()-Funktion Das ausgegebene Übereinstimmungsergebnis ist das Zeichen 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()
Die obige Implementierung erfordert zuerst das Kompilieren eines Musters und dann den Abgleich. Tatsächlich können wir die Funktion re.match(pattern, string)
direkt verwenden, um dieselbe Funktionalität zu erreichen. Die direkte Matching-Methode ist jedoch nicht so flexibel wie das Kompilieren und anschließende Matching. Erstens können reguläre Ausdrücke nicht wiederverwendet werden. Wenn eine große Datenmenge mit demselben Muster abgeglichen wird, ist jedes Mal eine interne Kompilierung erforderlich. Dies führt zu Leistungseinbußen; außerdem ist die Funktion re.match()
nicht so leistungsfähig wie pattern.match()
, die die Position angeben kann, von der aus mit dem Abgleich begonnen werden soll.
Kodierungsproblem
Nachdem Sie die Grundfunktionen regulärer Python-Ausdrücke verstanden haben, müssen Sie nur noch einen geeigneten regulären Ausdruck finden, der seltene Wörter und illegale Zeichen abgleicht. Unzulässige Zeichen lassen sich ganz einfach mithilfe des folgenden Musters zuordnen:
pattern = re.compile(r'[~!@#$%^&* ]')
Allerdings hat mich die Zuordnung seltener Charaktere wirklich verblüfft. Die erste ist die Definition seltener Wörter. Welche Art von Wörtern gelten als selten? Nach Rücksprache mit dem Projektmanager wurde festgestellt, dass Nicht-GB2312-Zeichen seltene Zeichen sind. Die nächste Frage ist: Wie werden GB2312-Zeichen abgeglichen?
Nach der Abfrage ist der Bereich von GB2312 [xA1-xF7][xA1-xFE]
und der Bereich für chinesische Schriftzeichen ist [xB0-xF7][xA1-xFE]
. Daher lautet der Ausdruck nach dem Hinzufügen seltener Wortübereinstimmungen:
pattern = re.compile(r'[~!@#$%^&* ]|[^\xA1-\xF7][^\xA1-\xFE]')
Das Problem scheint reibungslos gelöst zu sein, aber ich bin immer noch zu einfach und zu naiv. Da die zu beurteilenden Zeichenfolgen alle aus Layer-Dateien gelesen werden, kodiert arcpy die gelesenen Zeichen sorgfältig in das Unicode-Format. Daher muss ich den Codierungsbereich des GB2312-Zeichensatzes in Unicode herausfinden. Die Realität ist jedoch, dass die Verteilung des GB2312-Zeichensatzes in Unicode nicht kontinuierlich ist und die Verwendung regulärer Ausdrücke zur Darstellung dieses Bereichs sehr kompliziert sein muss. Die Idee, reguläre Ausdrücke zum Abgleichen seltener Wörter zu verwenden, scheint in eine Sackgasse geraten zu sein.
Lösung
Kann ich die bereitgestellte Zeichenfolge im Unicode-Format in GB2312 konvertieren und sie dann abgleichen? Tatsächlich ist dies nicht möglich, da der Unicode-Zeichensatz viel größer ist als der GB2312-Zeichensatz, sodass GB2312 => unicode
immer erreicht werden kann, umgekehrt unicode => GB2312
jedoch möglicherweise nicht unbedingt erfolgreich ist.
Das brachte mich plötzlich auf eine andere Idee. Angenommen, die unicode => GB2312
-Konvertierung einer Zeichenfolge schlägt fehl. Bedeutet das, dass sie nicht zum GB2312-Zeichensatz gehört? Also habe ich die Funktion unicode_string.encode('GB2312')
verwendet, um zu versuchen, die Zeichenfolge zu konvertieren und dabei die UnicodeEncodeError-Ausnahme abzufangen, um seltene Wörter zu identifizieren.
Der endgültige Code lautet wie folgt:
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
Zusammenfassung
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels für das Studium oder die Arbeit von Nutzen sein kann. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen.