Dragonito hat geschrieben:
Bei der Verarbeitung sind mir allerdings folgende Probleme aufgefallen. Ich habe ein Feld Vorwahl und ein Feld Telefonnummer. Jetzt ist nicht in jedem Feld die Vorwahl gefüllt sondern es kommt auch vor das im Feld Telefonnummern bspw. Die Vorwahl+Telefonnummer+Durchwahl drin hängen. Mal sind diese Daten mit "/" getrennt und dann wieder mit "-". Die Form "vorwahl/telefonnummer" bzw. "vorwahl-telefonnummer" lies sich relativ einfach splitten. Problem ist, ich weiss nicht wann die Nummer genau in den genannten Formaten auftreten.
Drago
Hi Dragonito,
erstmal muss ich sagen, dass ich staune ich, in welchem Tempo hier Antworten auf neue Themen folgen. Ich hoffe, mein Beitrag hier ist nicht schon überflüssig.
Zurück zum Thema: sofort als ich das Problem las, viel mir mein Lieblingsgebiet ein: Regular Expressions. Die sind für diese Art von Problemen predestiniert, da sie quasi maßgeschneidert werden können. Ohne viele Worte hier mal mein Lösungsvorschlag:
Code: Alles auswählen
import re, string
## erstelle kompiliertes re-patterns
creSegmentpattern = re.compile(r"((?P<vorwahl>\d+)[/ -])?(?P<nummer>.+?)([- ](?P<durchwahl>\d*))?$")
creZahlpattern = re.compile(r"\d+")
def teile_nummer(sTel):
oResult = creSegmentpattern.match(sTel)
if oResult:
dResult = oResult.groupdict()
dResult["nummer"] = reduce(string.join, creZahlpattern.findall(dResult.get("nummer")))
else:
dResult = {}
print "Telefonnummer mit unzulaessigen Zeichen oder Struktur eingegeben:", sTel
return dResult
print "Geteilte Nummer 1:", teile_nummer("05262/123 123 123 - 15")
print "Geteilte Nummer 2:", teile_nummer("05262/123123123-150")
print "Geteilte Nummer 3:", teile_nummer("05262 12312312315")
print "Geteilte Nummer 4:", teile_nummer("05262-123123123 15")
print "Geteilte Nummer 5:", teile_nummer("0526212312312315")
Ausgabe hat geschrieben:Geteilte Nummer 1: {'durchwahl': '15', 'vorwahl': '05262', 'nummer': '123123123'}
Geteilte Nummer 2: {'durchwahl': '150', 'vorwahl': '05262', 'nummer': '123123123'}
Geteilte Nummer 3: {'durchwahl': None, 'vorwahl': '05262', 'nummer': '12312312315'}
Geteilte Nummer 4: {'durchwahl': '15', 'vorwahl': '05262', 'nummer': '123123123'}
Geteilte Nummer 5: {'durchwahl': None, 'vorwahl': None, 'nummer': '0526212312312315'}
Was macht das Programm?
Einfach ausgedrückt: es beginnt vorn und erfasst die erste zusammenhängende Zahl bis zum ersten Leerzeichen, Minus oder Schrägstrich. Sind beide Bedingungen (Zahl und Endzeichen) erfüllt, wird diese Zahl dem Dictionaryschlüssel "vorwahl" zugeordnet. Dann werden alle weiteren Zeichen zusammengefasst und dem Schlüssel "nummer" zugewiesen, so dass am Ende eine Zahl übrig bleibt, die durch ein Leer- oder Minuszeichen von der Hauptnummer getrennt ist (wenn das möglich ist). Diese letzte Zahl wird mit dem Schlüssel "durchwahl" gespeichert. Zum Schluss werden die Sonderzeichen aus "nummer" entfernt.
Wie läuft das ab?
Als erstes werden die RegularExpression Muster kompiliert. Das ist eigentlich nur nötig, wenn man sehr viele Vergleiche damit durchführt, aber da ich nicht weiß, wie viele Einträge Du prüfst, ging ich lieber auf Nummer sicher.
Innerhalb der Funktion wird der als Parameter übergebene String vom Anfang an (match) nach einer Übereinstimmung für das beschriebene Muster durchsucht. Wird ein Muster gefunden, so wird ein Dictionary mit den Teilen zurückgegeben. Das Feld "nummer" kann Leer- und Minuszeichen enthalten. Deshalb werden über die zweite RegularExpression Funktion alle Vorkommen von Zahlen gesucht, die dann durch reduce wieder zu einem String zusammengesetzt werden.
Der verwendete RE Segmentpattern schrittweise erläutert:
r" - definiert als raw-string um sich mehrfache \ zu sparen
( - vorwahlsegment und Trennzeichen in Gruppe zusammenfassen
(?P<vorwahl> - Gruppe mit Label vorwahl definieren, die später über das dictionary abgefragt wird
\d+) - so viele aufeinander folgende Zahlen aufnehmen wie kommen (min. 1), dann Gruppenende
[/ -] - nach der Vorwahl muss ein /, leerzeichen oder - folgen
)? - Gruppe aus Vorwahl und Trennzeichen beendet, ? bedeutet, dass sie einmal oder keinmal vorkommt
(?P<nummer> - Gruppe mit Label nummer definieren
.+? - ein oder mehr beliebige Zeichen erlaubt, ? hinter + bedeutet, dass so wenig wie möglich Zeichen genommen werden
) - Ende der Gruppe nummer
([- ] - Beginn der letzten Gruppe, die mit Minus oder Leerzeichen beginnen muss
(?P<durchwahl> - Gruppe mit Label durchwahl definieren
\d*) - so viele zusammenhängende Zahlen wie möglich aufnehmen
)? - die Durchwahlgruppe kann einmal oder keinmal vorkommen
$" - der zu durchsuchende String muss nach der Durchwahlgruppe zuende sein
Alle Klarheiten beseitigt?
Grüße,
der Michel