Reguläre Ausdrücke

#1

Hallo,

ich will für mein Shop ein kleines Tool entwickeln, dabei habe ich ein Problem mit regulären Ausdrücken. Ich suche mit folgenden Code

~<th class="left">irgend ein Text(.*)</th>(\r\n)?<td>(.*)</td>~isU

Suche ich nur wie folgt
~<th class="left">irgend ein Text (.*)</th>~isU, bekomme ich die Daten in der Klammer, da sich aber das <td>(.*)</td> in einer neuen Zeile befindet, bekomme ich ein leeres Array. Ich habe schon viele mögliche Varianten getestet aber keine funktioniert. Eventuell kann mir hier jemand weiter helfen.

nochmal der komplette Code:

$str = '<th class="left">irgend ein Text</th>
<td>irgend ein anderer Text</td>';

$pattern = '~<th class="left">irgend ein Text(.*)</th>(\r\n)?<td>(.*)</td>~isU';                
preg_match_all($pattern,$str,$match);
print_r($match);

Grüße aus Berlin

#2

ich bin mir nicht sicher, was das mit OXID zu tun hat, aber es sollte ([\r\n]?) statt (\r\n)? sein

#3

Hab mir schon gedacht, dass die Frage kommt, mit Oxid selbst hat es nichts zu tun, eher mit meinem Oxid Shop und wie erwähnt ein Analyse Tool welches ich entwickle, die zu analysierende Datei liegt auf meinem Server und wir per file get contents eingelesen.

Wie auch immer, dein Vorschlag funktioniert leider auch nicht, für weitere Vorschläge wäre ich sehr dankbar.

Wie geschrieben, einzeilig ist es kein Problem, geht es aber über 2 oder mehr Zeilen, funktioniert es nicht mehr.

#4

im Validator funktioniert es:

ggf sind html entities drin? oder versuch mal global und multiline modifier

#5

Teste ich morgen mal. Multiline ist mir bekannt aber was ist global bzw. das Kürzel und was bewirkt es? Soweit mir bekannt ist, sind keine html entities enthalten.

#6

Danke nochmal Problem über Umwege gelöst.

#7

Itnic. Das Problem mit deinem Regex sind diese punkte+Stern. Dann fängt die Analyse auf einmal an rückwärts zu lesen und macht meisten alles zwischen drin kaputt.

Das wäre dein RegEx: <th[^>]+>([^<]+)</th>\s*<td>([^<]+)</td>

Der geheim trick liegt im Syntax [^.Dies ist eine Verneinung. Mal schauen ob ich das erklären kann: Ausgeschrieben sieht es so aus [^>]+ Der nächste Buchstabe darf nicht ‘>’ sein. Also sammelt er alle Buchstaben ein genau so wie .+. Nur der Vorteil ist die routine bleibt immer noch von links nach rechts lesend, Buchstabe für Buchstabe. Er hört dann erst auf zu sammeln wenn > gefunden wird. Damit es weiter geht, muss zum Schluss nochmal ‘>’ stehen. Der regex lautet nun ... [^>]+> ....

Das ist die alternative zu .* Diese alternative ist viel effektiver und sicherer.

#8

@TumTumi,

ich verstehe schon was du mir sagen willst, dass ist aber nicht das eigentliche Problem, sondern der Zeilenumbruch, ab </th> hört er auf zu lesen für mich ist aber der Inhalt in <td>([^<]+)</td> entscheidend und der ist nun mal in einer neuen Zeile und da hilft auch dein Ansatz leider nicht.

1 Like
#9

Du brauchst ‘s’ als Flag (Handle as 's’ingleline) und Positive Lookaheads etc.

Kommt das hin? https://regex101.com/r/nQaW2c/2

1 Like
#10

@Sioweb

Danke das war es :grinning:

#11

@Sioweb dein Regex ist gut! Jedoch dann kannst du auch sowas schreiben: https://regex101.com/r/2KK7FX/1

Bei dem vorherigem passt es auch mit Zeilenumbrüche https://regex101.com/r/feG1RG/1

Jedoch @itnic würde ich dir empfehlen einen HTML Parser zu nehmen. Dann brauchst du das Rad nicht neu erfinden. Seit 1997 versucht man schon HTML zu analysieren: https://packagist.org/?query=html%20parser

Viel erfolg mit deinem Project!