Ort aus Telefonnummer erkennen
Riko
- php
0 Henryk Plötz0 Robin
Hallo liebes Forum,
hat jemand eine Idee wie ich aus einer Telefonnummer (Format 04012345678) den dazugehörigen ort ermitteln kann?
Eine Tabelle im CSV-Format in der Form
Hamburg;040
...
liegt mir vor, aber wie mache ich das jetzt?
Wär toll, wenn jemand eine Idee hat - PHP mache ich leider erst seit kurzem :-))
Riko
Moin,
hat jemand eine Idee wie ich aus einer Telefonnummer (Format 04012345678) den dazugehörigen ort ermitteln kann?
Eine Tabelle im CSV-Format in der Form
Hamburg;040
...liegt mir vor, aber wie mache ich das jetzt?
Wär toll, wenn jemand eine Idee hat - PHP mache ich leider erst seit kurzem :-))
Hmm, das "in schön" hinzukriegen ist gar nicht so einfach.
1. Der einfache Weg
Wenn du deine Tabelle schon nach Zeilen und Spalten aufgesplittet hast, könntest du zum Beispiel in einer Schleife alle Ziffern aus deiner Nummer durchgehen und schauen ob die Nummer bis zu der jeweiligen Ziffer eine Vorwahl ist. Für dein Beispiel also: Schaue nach ob irgendwo "0" als Vorwahl verzeichnet ist - Nein - Schaue nach ob irgendwo "04" als Vorwahl verzeichnet ist - Nein - Schaue nach ob irgendwo "040" als Vorwahl verzeichnet ist - Ja, Antwort ist Hamburg. Da die Vorwahlen eindeutig sind, sollte das in jedem Fall die korrekte Antwort geben. Das war die einfachste aber auch langsamte Methode. Im Durchschnitt brauchst du hierfür (durchschnittliche Länge einer Vorwahl)\*(Länge der Liste) Vergleiche.
2\. Der Weg mit den regulären Ausdrücken
Du könntest das auch in einem Schritt machen, indem du aus deiner Telefonnummer einen regulären Ausdruck baust, der die Suche durchführt. Aus 04012345678 müsstest du 0(4(0(1(2(3(4(5(6(7(8)?)?)?)?)?)?)?)?)?)? machen (vorher sicherstellen, dass die Eingabe nur aus Ziffern besteht!). Das sucht, wenn ich mich nicht vertan habe, nach einer 0, die von einer 4 gefolgt sein kann, die von einer 0 gefolgt sein kann, die von einer 1 gefolgt sein kann, usw. wobei die hinteren Zahlen nur vorkommen dürfen, wenn eine der vorderen Zahlen schon da war. Das findet also 0, 04, 040, 0401, 04012 usw. aber nicht 001 oder 0402 oder so. Diesen regulären Ausdruck wirfst du jetzt auf deine Tabelle und raus kommt die Zeile mit dem Ort. Das ist eine Methode mit vergleichsweise guter Performance und noch nicht so kompliziert. Hierfür muß das preg_match() im schlimmsten Fall (kein Treffer) einmal über deine gesamte Liste wandern.
3. Der Weg mit dem Baum
Der Königsweg wäre aber (meiner bescheidenen Meinung nach) ein Suchbaum. Dazu müsstest du deine Tabelle zuerst umformen, was dann jedoch nur einmal gemacht werden muß (ich gehe davon aus, dass die sich nicht täglich ändert, oder?).
Du baust dir also einen Baum aus Blättern auf, wobei jedes Blatt einen Teil einer Vorwahl darstellt und als Kind alle anderen Vorwahlen mit diesem Anfang oder aber den einen Ort mit dieser Vorwahl hat. Das lässt sich in PHP relativ einfach über Arrays simulieren:
$d[0] ist ein Array über alle Vorwahlen die mit 0 anfangen (das sollten alle sein)
$d[0][1] ist ein Array über alle Vorwahlen die mit 01 anfangen
...
$[0][4] ist ein Array über alle Vorwahlen die mit 04 anfangen
$[0][4][0] ist der String "Hamburg"
$[0][4][1] ist ein Array über alle Vorwahlen die mit 041 anfangen
...usw. usf.
Das Array kannst du einmal erzeugen und dann immer wieder verwenden (speichern und laden zum Beispiel über serialize() und unserialize()). Wenn du die Beispielnummer nachschlagen willst, schaust du zuerst ob $d[0] existiert und ein Array oder ein String ist -> ein Array, also schaust du nach ob $d[0][4] existiert und ein String oder ein Array ist -> ein Array, also nachschauen was mit $d[0][4][0] ist -> der String "Hamburg", deine Nummer gehört also nach Hamburg. Wenn du bei einem der Schritte auf etwas anderes als einen String oder ein Array triffst, dann kannst du abbrechen und sagen, dass mit der Nummer etwas faul ist.
Diese Methode braucht im schlimmsten Fall (Länge der längsten Vorwahl) Operationen, wenn der Baum schon vorliegt.
Beispielcode für die Wege 2 und 3
<?php
// Eingabe in $eingabe
/*
if(!preg_match("![1]+$!", $eingabe))
die("Eingabe darf nur aus Zahlen bestehen");
$regexp = $eingabe{strlen($eingabe)-1};
for($i=strlen($eingabe)-2; $i>=0; --$i)
$regexp = $eingabe{$i}."(".$regexp.")?";
*/
// $regexp enthält jetzt den regulären Ausdruck
?>
<?php
// Die Zeilen der Liste sollten in $liste sein
// d.h. $liste sollte ein Array mit Einträgen
// der Form "foo;0815" enthalten
$d = Array();
foreach($liste as $zeile) {
list($ort, $vorwahl) = explode(";",$zeile);
$ort = trim($ort); $vorwahl=trim($vorwahl);
if(!preg_match("![2]+$!", $vorwahl)) {
echo "Warnung: $zeile entspricht nicht ".
"dem Format. Ignoriert.\n"; next;
}
$blatt = &$d;
for($i=0; $i<strlen($vorwahl); ++$i) {
if(isset($blatt[$vorwahl{$i}])){
if(!is_array($blatt[$vorwahl{$i}]))
die("Huch, ".substr($vorwahl,0,$i).
"ist schon mit ".$blatt[$vorwahl{$i}].
"belegt. Abbrechen!\n");
} else $blatt[$vorwahl{$i}] = Array();
$blatt = &$blatt[$vorwahl{$i}];
}
$blatt = $ort;
}
unset($blatt);
// Schnipp, an dieser Stelle könnte $d gespeichert
// und später wieder hervorgeholt werden
// Jetzt die Nummer in $eingabe raussuchen
if(!preg_match("![3]+$!", $eingabe))
die("Eingabe darf nur aus Zahlen bestehen");
$blatt = $d;
for($i=0; $i<strlen($eingabe); ++$i) {
if(isset($blatt[$eingabe{$i}])) {
if(is_string($blatt[$eingabe{$i}])) {
$antwort = $blatt[$eingabe{$i}];
break;
}
$blatt = $blatt[$eingabe{$i}];
} else {
echo "Die Vorwahl ist nicht verzeichnet.";
break;
}
}
// Die Antwort ist in $antwort
?>
Hi!
Eigentlich eine interessante Sache mit den Telefonnummern/Orten!
Wo gibt es denn ein solches CSV-File oder wie käme ich da dran?
Hast du das lizensiert oder könntest du mir das schicken?
Wäre echt toll!!
Robin