PHP preg, explode und strings

mercsen

Lt. Commander
Registriert
Apr. 2010
Beiträge
1.680
Moin,

in meinem aktuellem projekt muss ich eine Schnittstelle zu dem Bugtracker JIRA entwickeln. Bin damit jetzt zu 99% fertig und scheitere an einer eigentlich ziemlich trivialen aufgabe.

ich kommuniziere über die REST API mit dem bugtracker und lade mir die entsprechenden Daten vom Server.

Ich habe nun in PHP Klassen erzeugt die, die empfangenen Daten verarbeiten und Kapseln, doch nun scheitere ich am Parsen der Kommentare.

Da mein Kunde im JIRA nur eine begrenzte Anzahl von Accounts anlegen darf, haben wir einen user "public" erzeugt der nun bei freigegeben Issues kommentare posten darf, über die von mit entwickelte Schnittstelle.

Das heißt alle kommentare kommen vom user "public", damit ich im Kundencenter meiner schnittstelle nun aber trotzdem unterscheiden kann welcher "wirkliche" user das Kommentar geschrieben hat, lasse ich jedem Kommentar 2 Zeilen vorwegstellen.

USER#XXXX
$ABC (Firma $DEF) schrieb am 12.10.2012 um 14:33 Uhr

mit X € N > 0 (die intere userid)
$ABC ist der Interne Username und $DEF ist die Firma zu der der User gehört.


Diese 2 Zeilen brauche ich in meiner Schnittstelle aber nicht und will sie rausscheniden, habe es mit einem regulären ausdruck versucht der auch funktionieren 'sollte'

In dem Programm regex coach fuktioniert er, aber in php nicht.
Irgendwie geht mir was mit den Umbrüchen ab.

folgender code funktioniert z.b.
(jetzt folgender code ist nur aus frust entsatnden um das problem zu finden)

Code:
$this->body = preg_replace('/\\n/', '##%##', $this->body);
            $this->body = explode('##%##', $this->body);

dann habe ich einen Array in dem pro key eine zeile steht

folgender code geht aber nicht

Code:
 $this->body = explode('\n', $this->body);

dann habe ich immer nur ein element, welches den gesamten Text enthält.

Kann mir da einer erklären wieso ich den Umbruch als regulären ausdruck finde, aber nicht per explode? (habe schon dutzendemale nen string mit explode('\n') zerlegt, ich raffs net)

ich habe es btw. mit dem regex versucht

Code:
$this->body = preg_replace('/user#\d+\\n([a-zA-Z ():0-9\.])*\\n{2}/', '', $this->body);

der soll mir halt einfach die ersten 2 zeilen löschen, leider muss der so allgemein gehalten werden da sich der Text auch ändern kann, als ende ist eigentlich nur entscheidend das 2mal ein \n auftaucht.

das interessante ist halt, wenn ich z.b. erst mit preg_replace alle \n ersetze, funktioniert mein regulärer ausdruck, aber sonst nicht. Finde das sehr merkwürdig, hat da jemand eine erklärung?

ich habe den ausdruck auch mittlerweile optimiert, mir geht es jetzt nur um dieses komische verhalten.
 
Versuch mal, ob er den Zeilenumbruch richtig erkennt, wenn du die Konstante PHP_EOL statt "\n" verwendest.
 
ja tut er....

bei gegebenen Kommentar
Code:
user#1234
Dieter (Firma ABC) schrieb am 12.10.2012 um 19:33 Uhr:

Hallo, hier ein Kommentar von mir

lasse ich folgenden Code laufen

PHP:
$this->body = preg_replace('/\\r/', '-', $this->body);
$this->body = preg_replace('/' . PHP_EOL . '/', '+', $this->body);

ergibt folgende ausgabe:

Code:
user#1234-+Dieter (Firma ABC) schrieb am 12.10.2012 um 19:33 Uhr:-+-+Hallo, hier ein Kommentar von mir

und trotzdem erzeugt
PHP:
$this->body = explode('\r\n', $this->body);

ein array mit nur einem element! Ich kapiers nicht.

edit:

PHP:
preg_match_all('/\\r\\n/', $this->body, $this->t);

erzeugt einen Array mit genau 3 elementen, er findet also alle 3 Umbrüche, allerdings nur als regulären ausdruck :-/

und mit
PHP:
preg_match_all('/(.*\\r\\n)/', $this->body, $this->t);
kann ich mir alle zeilen (bis auf die letze da kein abschließendes \r\n vorhanden) anzeigen lassen und ggf. filtern, erscheibt mir aber argh umständlich.

Ich will doch nur mit einem preg_replace alles löschen bis \r\n{2} auftaucht :(

leider scheint dort das problem zu sein, zu erkennen das 2 neue zeilen hintereinander folgen
 
Zuletzt bearbeitet:
Mercsen schrieb:
Code:
$this->body = preg_replace('/\\n/', '##%##', $this->body);
            $this->body = explode('##%##', $this->body);
entweder regext du vernünftig (ein backslash, der ein sonderzeichen escaped, wird nicht escaped, sonst wird eben dieser escaped backslash als backslash behandelt und nicht als escaper von dem n)->
Code:
$this->body = preg_replace([COLOR="red"][B]'/\n/'[/B][/COLOR], '##%##', $this->body);
            $this->body = explode('##%##', $this->body);

Mercsen schrieb:
Code:
 $this->body = explode('\n', $this->body);
oder du explodest vernünftig:
Code:
 $this->body = explode([B][COLOR="Red"]"[/COLOR][/B]\n[B][COLOR="red"]"[/COLOR][/B], $this->body);

aber ist ja nicht so, dass das hier schonmal erwähnt wurde:
Yuuri schrieb:
'\n' wird nix, das heißt "\n".
 
die antwort von yuuri war für mich leider net sichtbar. ja das "\n" hats gerissen.

bei dem regex macht es aber keinen unterschied ob ich nach \\n oder \n suche, erzeugen die selben ergebnisse.

einfach zu lange keine string operationen mehr gemacht.

wird zeit das " endlich aus php verschwindet.

danke soweit (außer an rumbalotte)

Code:
$this->body = preg_replace('/.*\r\n.*(\r\n){2}/', '', $this->body,1);

macht nun was ich will

auch wenn ich nicht ganz verstehe wieso
Code:
$this->body = preg_replace('/.*(\r\n){2}/', '', $this->body, 1);

nur die zweite zeile filtert. Hätte ich in Automathentehorie und Formale Sprachen nur besser aufgepasst -_-

nach meinem verstädnis heißt der ausdruck: Suche egal was, bis du 2 zeilenumbrüche findest.
 
Zuletzt bearbeitet:
Mercsen schrieb:
wird zeit das " endlich aus php verschwindet.

Es wird wohl eher Zeit den Unterschied zwischen String Variablen und String Literalen zu verstehen :)

Diese Unterscheidung ist durchaus sinnvoll und gibt es fast ausnahmslos in allen populären Programmiersprachen.
 
Versuch mal
PHP:
$this->body = preg_replace('/.*(\r\n){2}/s', '', $this->body, 1);
Das 's' ist der Modifikator PCRE_DOTALL. Wird dieser nicht angegeben, dann matcht der Punkt keine Zeilenumbrüche, d.h. ein '.*' kann immer höchstens eine Zeile erkennen.
 
Zurück
Oben