Elemente zw. 2 Variablen extrahieren
Lars
- php
Hallo,
ich verzweifele schon die ganze Nacht daran, ich würde mich sehr freuen, wenn jemand mir einen Hinweis geben könnte.
Folgendes:
Ich möchte aus einer vollen Textdatei einige Werte extrahieren und zwar die, die sich zwischen "(" und ")" befinden.
Nur irgendwie komme ich nicht weiter.
ich habe die Textdatei in einen Array eingelesen und nun habe ich alles mögliche durch(wie Erstetzen, Trennen u.s.w.), aber leider nicht das richtige gefunden :(
Beispiel:
vw golf-blah (2.500), bmw-blah blah(10000), opel-blah blah(50
00)-totalschaden., ......
ich möchte die Preise extrahieren können, um sie später zu berechnen. Mir ist klar daß dies eigentlich mit sql kein Problem darstellt, leider lässt sich das mit der Textdatei nicht ändern.
Hat jemand einen Rat, wie ich das bewerkstelligen kann?
Vielen Dank
Lars
P.s: Sorry für eventuelle Rechtschreibfehler, bin müde, komme aber nicht ins Bett , da ich mich festgebissen habe...immer das gleiche;)
Hi Lars,
probiers mal hiermit:
<?php
$string = "Hallo {qwer}was auch {immer} {i} {horst}";
preg_match_all ("/({)([a-zA-Z0-9]+)(})/", $string, $matches);
for ($i=0; $i< count($matches[0]); $i++) {
echo "matched: ".$matches[0][$i]."<br>";
echo "part 1: ".$matches[1][$i]."<br>";
echo "part 2: ".$matches[2][$i]."<br>";
echo "part 3: ".$matches[3][$i]."<br>";
}
?>
hier die Erklärung dazu:
http://www.php.net/manual/de/function.preg-match-all.php
Beispiel 2
Gruss
Horst
und ... geht mal schalfen: Gute Nacht
Guten Tag Lars,
ich will mal versuchen, die ein wenig Verständnis von Dateien zu vermitteln. :-)) Das macht die Sache leichter.
ByTheWay:
Ich möchte aus einer vollen Textdatei einige Werte extrahieren und zwar die, die sich zwischen "(" und ")" befinden.
**ggg* das ist der Beweis dafür dass es von VOLL doch eine Steigerungsform geben muss. Meine Textdatei ist nämlich bestimmt voller. :-)
Also nun zum Thema:
in klassischen Dateisystemen mit Direktzugriff haben Dateien auf dem Medium (HDD) zwar einen Anfang, aber kein vordefiniertes Ende. Man merkt sich in einer Liste (Directory) in welchem Bereich (Cluster/Block) des Mediums die Datei beginnt. Eine separate Funktion stellt der Datei solange weitere Blöcke zur Verfügung, wie diese sie benötigt. Dazu benutzt sie den FAT (File Allocation Table) oder ähnlich intelligente[tm] Mechanismen, um die Kette der Blöcke jederzeit wiederfinden zu können.
Das Wesentliche dabei ist, dass auf dieser Ebene alles LINEAR organisiert ist. Das bedeutet, dass ein Byte nach dem nächsten folgt und es keine Verzweigungen gibt. Die meisten Betriebssysteme können auch einmal für die Datei belegten Platz nicht wieder zurückgeben, ohne die Datei als Ganzes zu verlieren.
Wenn Du nun eine Textdatei speicherst, dann ist das in Wirklichkeit also auch nur EINE Kette von Bytes. Dem Dateisystem ist es dabei (es gibt Sonderfunktionen in der Tranferschicht, die uns hier aber nicht interessieren) egal, ob Du Zeilenschaltungen machst oder nicht. Die Zeilenschaltungen werden einfach als inline-command ein den Zeichenstrom eingebettet. Erst Dein Darstellungsprogramm findet diese Zeichen wieder und schaltet dann eben in eine neue Zeile, anstatt es anzuzeigen.
auf der Platte:
AAAAAAAAAAAAAAAAAAAAAAAA#AAAAAAAA#AAAAAAAAAA##AAAAAAAAAAAAAAAAAAAAAAAAA
Auf dem Bildschirm:
AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA
AAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAA
Ich habe hier die As als Synonym für Buchstaben und die #s als Synonym für das Zeilenschaltungszeichen benutzt. In den gängigen Systemen benutzt man für
System Mnemonic Zeichen in Dec Bedeutung
DOS/WINDoofS: CRLF 13 10 Carriage-Return Line-Feed
Unix/Linux LF 10 Line-Feed
MAC CR 13 Carriage-Return
DOS kam als letztes System und kann, wenn die Programme nach den Wünschen der Entwickler geschrieben werden, mit allen dreien umgehen, fügt aber selber immer CRLF ein. Wenn Du Programme schreibst, solltest Du auch darauf achten, dass die mit allen drei Darstellungen klar kommen.
So, nun ein Stück Philosophie:
Wenn Du aus einem Zeichenstrom Sequenzen (hintereinanderstehende Zeichen) entfernen willst, dann brauchst Du sie beim Kopieren doch nur zu unterdrücken. Allerdings solltest Du in Deinem Fall darüber nachdenken, ob nicht innerhalb der Sequenz stehende besondere Zeichen trotzdem übertragen werden sollten:
AAAAAAAAAAAAAAAAA(BBBBBBBBBBB#BBBB)AAAAA#AAAAAAAAA#AAAA(BBBBBBBBB)AAAAAAAA
|
+-- hier steht ein Zeilenumbruch mitten in der
zu entferndenen Sequenz
Es ist nun wirklich Philosophie, ob Du den erhalten willst, oder nicht. Ich Würde es tun. Stell Dir das ganze mal in Word vor. Du willst ja nur den missliebigen Text entfernen, nicht aber den übrigen Aufbau des Dokumentes zerstören. Es könnte sich ja auch um Datensätze handeln, die jeweils durhc eine Zeilenschaltung voneinander getrennt werden. Und dann würde ja später einer fehlen...
Nun zu Deinem Programm:
Öffne die Datei zum Lesen binär, das bedeutet rein zeichenoreintiert.
$fh = fopen("dateiname","r");
lies sie in EINE Variable ein, hoffentlich sit die Datei nicht zu groß.
Bei PHP würde ich mir aber da bis zu ca. 30% des freien Hauptspeichers keine Gedanken machen.
$var = fread($fh);
und schließe die datei wieder, damit die Blockbuffer wieder freigegeben werden können.
fclose($fh);
Nun kannst Du zur Probe mal danach fragen, wie groß Deine Variable ist:
echo strlen($var);
Stimmt das mit der Dateigröße überein?
Nun kannst Du schon beginnen, deine missliebigen Sequenzen zu entfernen. Du kopierst dazu einfach solange Byte für Byte, bis das Startzeichen der Sequenz kommt. Innerhalb der Sequenz lässt Du nur die beiden für die zeilenschaltung reservierten Sonderzeichen durch. Erst wenn das Sequenzende-Zeichen vorbei ist, kopierst Du wieder jedes Zeichen:
$var2="";
for ($i=0; $i<$len); $i++)
{
if($var[$i]="(")
{
$copyflag = false; // ab hier nicht mehr kopieren
}
if (($var[$i]=chr(13)) or ($var[$i]=chr(10)) or ($copyflag))
{
$var2+=$var[$i];
}
if($var[$i]=")")
{
$copyflag = true; // ab dem nächsten Zeichen wieder kopieren;
}
}
Wenn man das ganez noch ein klein Wenig beschligen will, dann holt man sich das Zeichen an der Stelle [$i] einmal pro Schleifendurchlauf:
$zeichen = $var[$i];
und arbeitet dann in der Schleife damit.
Das Zurückkopieren der $var2 in eine Datei bekommst Du dann bestimmt hin.
Liebe Grüße aus http://www.braunschweig.de
Tom