Regulärer Ausdruck: String-Endung negieren

Sturmrider

Erfahrenes Mitglied
Guten Morgen :)

Ich probiere nun schon seit 1h einen regulären Ausdruck hin zu bekommen. Leider bin ich ein wenig eingerostet und es klappt einfach nicht so, wie ich möchte. Folgender Ausdruck soll alle Links zulassen bzw. finden, die nicht auf .jpg oder .gif oder .png usw, enden...
Code:
/([\w]+:\/\/[\w-?*&;#~=\.\/\@]+[\w\/]+^(\.[jpg|gif|png|jpeg|JPG|GIF|PNG|JPEG]))/i
Leider funktioniert es nicht, hat jemand eine Idee warum nicht?
 
Nein, ich denke das geht schon in Ordnung was ich da mache. Der reguläre Ausdruck ist teil von preg_replace() und ich durchsuche eine geparste Webseite bzw. einen Teil von ihr. ;)
Bevor weitere Fragen kommen: Ich parse meine eigene Webseite und möchte alle externen Links (welche jedoch keine Bild-Links sein sollen) zu meinem Dereferer weiter leiten. Links zu filtern ist kein Problem, auch Bild-Links nicht, jedoch Links die keine Bild-Links sind. Halt obiges Problem.
Hätte ich das Problem wovon du ausgegangen bist, würde ich auf strrpos() zurück greifen. Das wäre noch einfacher, als du vorgeschlagen hast ;)

Edit: Mir ist klar, dass ein Bildlink nicht auf Datei-Endungen enden muss. In diesem Fall ist es egal, wenn der Bild-Link als normaler Link behandelt wird.
 
Zuletzt bearbeitet:
In diesem Fall (sofern richtig verstanden) empfehle ich dir folgendes:
Schlucke per regulären Ausdruck alle URL aus "<a href='...'" und filter diese nach "extern" und "kein Bild".
Das kostet weniger Rechenzeit als wenn preg immer hin und her springt im Text um das Dateiende zu erfahren UND ob es intern / extern ist. (Tip: Nimm ein RegExp tool und lasse dies mal Schrittweise ausführen, dann siehst die enorme Arbeit)
Diese (gefilterte) Liste (mit href= voran) kannst du dann durch str_replace() jagen.
 
Da hast du mich leider falsch verstanden. Wie bereits geschrieben, ich durchsuche eine geparste HTML-Seite und möchte die Links durch einen Dereferer-Link (also z.B. http://meine-domain.de/index.php?dereferer=http://www.google.de) ersetzen. Allerdings sollen hierbei Bild-Links ausgeschlossen werden. Aus diesem Grund kann ich hier in PHP nur effektiv mit regulären Ausdrücken arbeiten und nichts anderem.
Ach Mensch... langsam ärgert es mich richtig, dass ich so lange keine mehr benutzt habe und meine Uni-Unterlagen nicht finde... :(

EDIT: Übrigens glaube ich nicht, dass ein regulärer Ausdruck sehr viel langsamer wäre, als dein oben genannter Vorschlag. Soweit ich mich erinnere können Typ 3 Grammatiken außerhalb des Compilers arbeiten und somit viel schneller und effektiver agieren. Wie jedoch reguläre Grammatiken in PHP implementiert sind, weiß ich nicht genau.
 
Zuletzt bearbeitet:
Hmm, also viele Links wird man damit aber nicht finden können, da ist mein Ansatz doch um einiges genauer :-( (nicht böse sein)
Du würdest z.B. die URL dieser Seite nicht finden können. Naja und um das Negieren geht es hier ja in erster Linie. Ohne diesen Teil funktioniert mein Ausdruck einwandfrei...
Ich habe jetzt schon einige Seiten zu Hilfe gezogen und auch meine Uniaufzeichnungen wieder gefunden... leider bringt mich das jedoch nicht weiter. Look-ahead assertion und look-behind funktionieren irgendwie nicht :( auch wenn ich noch einen kleinen Fehler bei mir gefunden habe... anstelle eckiger, müssten dort runde Klammern ans Ende
Code:
/([\w]+:\/\/[\w-?*&;#~=\.\/\@]+[\w\/]+?!(\.(jpg|gif|png|jpeg|JPG|GIF|PNG|JPEG)))/i
Trotzdem funktioniert es nicht :confused:

EDIT: Oh, timestamp hat seine Nachricht gelöscht ^^
 
Zuletzt bearbeitet:
Hallo Sturmrider,

du könntest ZodiacXPs ersten Vorschlag mit einem regulären Ausdruck kombinieren, der zunächst mal alle URLs rausfiltert. Die Entscheidung, ob und wie eine URL dann ersetzt werden soll, machst du in einem Callback. Siehe [phpf]preg_replace_callback[/phpf].

Grüße,
Matthias
 
Okay :D das ist auch eine Möglichkeit, an die ich noch gar nicht gedacht habe ^^ danke euch beiden!
Sollte jedoch noch jemand eine Lösung für den regulären Ausdruck finden, würde ich mich über einen kurzen Post freuen ;) Ehrlich gesagt fuchst mich das mittlerweile ganz schön...
 
Hallo,

ein negativer Lookbehind in Verbindung mit possessiven Quantifizierern sollte funktionieren:
Code:
https?:\/\/[^\/]+\/\S++(?<!\.(jpg|png|gif))(?<!\.jpeg)
Das URL-Muster habe ich etwas vereinfacht. Wichtig ist der possessive Quantifizierer ++, welcher ein Backtracking beim Fehlschlagen des Lookbehinds verhindert. Lookbehinds müssen außerdem konstant in ihrer Länge sein, deswegen kann man .jpeg nicht zu den anderen Endungen hinzunehmen, sondern braucht ein zusätzliches Lookbehind.

Grüße,
Matthias
 
  • Gefällt mir
Reaktionen: bn
Hallo Matthias,

ich hatte ebenfalls versucht, für das Problem eine Lösung zu finden. Bin jedoch am Backtracking gescheitert. Bilder auf JPG endend wurden beispeilsweise zwar erkannt, aber bis zum P replaced. Mit dem ++ funktioniert nun auch mein gestern weiter entwickeltes Pattern. Das Pattern werde ich mir gleich mal weg speichern, kann man immer mal gebrauchen :-).

Code:
/([\w]+:\/\/[\w\-\?*&;#~\=\.\@]+[\w\/\.]++(?<!\.jpg|\.gif|\.png)(?<!\.jpeg))/i

Wieder was zu gelernt, danke.

BN
 
Zurück