s.oliver: Regex immer mal wieder

Beitrag lesen

Servus,

Scheint zu klappen, dann trau ich mich doch glatt mal weiter.
Jetzt das gleich aber ich will alles zwischen " haben was nicht
den Begriff "html" enthält.

Also:
!"[^"]*?^html*[^"]*?"!is    Das klappt dann aber wieder nicht ;-(

Das Caret (^) hat in Regulären Ausdrücken zwei Bedeutungen:
1. Als Indikator für den Anfang des Strings oder den Zeilenanfang nach einem Umbruch - wohl das häufigere Anwendungsgebiet
2. Als Negationszeichen innerhalb einer Charakterklasse (und nur da)

In Deinem Beispiel versuchst Du also möglicherweise, einen String zu finden, bei dem vor 'html' ein Zeilenumbruch stattfindet. ;-)

Grundsätzlich könntest Du natürlich einfach zwei Bedingungen verknüpfen, wobei Du testest, ob die Substrings a) der richtigen Form entsprechen und b) einen bestimmten String nicht enthalten ( preg_match( '/^"[^"]*?[^" ]+[^"]*?"$/i'... && !preg_match( '/html/'... so in der Art ) - ich nehme aber mal an, das ist jetzt nicht Sinn und Zweck der Übung.

Eine andere Möglichkeit wäre, einen negativen Lookahead zu verwenden; dabei prüft die Engine sozusagen, ob vor der jetzigen Position des internen Zeigers eine bestimmte Zeichenkette nicht gefunden werden kann, ohne diese Kette aber in das Ergebnis mit aufzunehmen (normalerweise würde die Engine jedes Zeichen was dem Suchmuster entspricht 'fressen', d.h. für das letztendliche Ergebnis festhalten). Dieses spezielle Verhalten hat den Vorteil, das wir, ohne irgendetwas in Speicher oder Resultset zu kopieren, erst einmal testen können, ob eine Kette vorhanden ist; ist sie vorhanden, erzeugt die negative Lookahead assertion einen Fehler und die Engine sucht sich den nächsten Kandidaten.

Ich schlage vor, Du liest Dir erst mal in der Quelle Deiner Wahl etwas zu Lookahead und Lookbehind assertions durch, falls das noch nicht viel Sinn gemacht hat.

In Deinem speziellen Beispiel (Sonne und html), könnte der Ausdruck in etwa so aussehen: /"((?![^"]*html[^"]*)[^"]*[^" ][^"]*)"/.

Grüsse