Regex zeigt zu viel an

tutfrank

Grünschnabel
Hallo Ihr Lieben,
brüte schon seit 2 Tagen an folgendem Problem rum. Ich möchte bei a-tags nur den Hyperlink ausgeben. Hier das Beispiel eines kompletten Tags:
<a href="file:///Users/frankpaul/Library/Mobile%20Documents/com~apple~CloudDocs/WSL_CMS/home.html"><span class="s2"><span class="s2">Home</span></a>. In diesem Fall soll also Home ausgegeben werden.
Dazu habe ich folgenden Regex erstellt: \>(.*?)<\/
Das funktioniert bei einfachen tags wie <a href=home.html>Home</a> perfekt. Wenn ich aber - wie im Beispiel - noch Span-Elemente oder Ähnliches drin habe, erhalte ich zuviel zurück. In dem oberen Beispiel dann: <span class="s2"><span class="s2">Home statt nur Home. Weiß jemand Rat, wie ich erst ab dem letzten > vor dem Text ausgeben lassen kann?
Ich freue mich auf Euer Feedback. :)
Anbei das Beispiel auf regex101.com
 

Anhänge

  • Bildschirmfoto 2023-06-18 um 22.35.51.png
    Bildschirmfoto 2023-06-18 um 22.35.51.png
    365,7 KB · Aufrufe: 1
Dies funktioniert bei mir:
Code:
<a\s+href.*>([^<]+)<.*<\/a>
oder, einfacher, wenn Du nur diesen String ohne weiteres HTML hast:
Code:
>([^<]+)<
D. h. hinter einer schließenden spitzen Klammer nur die Zeichen zulassen, die ungleich einer öffnenden sind.

Übrigens ist dein HTML fehlerhaft: Zwei öffnende <span class="s2"> aber nur ein schließendes </span>

Und es stellt sich die Frage, wozu Du die spans brauchst. U. U. kannst Du das selbe erreichen wenn Du dem a-href-Tag die Klasse "s2" gibst.
 
Hallo Sempervivum,
vielen Dank für die schnelle Antwort. Echt super.
In regex101 funktioniert es super, in meinem Code leider nicht. Hier die komplette Zeile:
preg_match('/\<a\s+href.*\>([^\<]+)\<.*\<\/a\>/', html_entity_decode($inhalt), $matches);
Ich werde es morgen nochmal probieren. Ist sicher nur ein kleiner Fehler.
Die Spans brauche ich eigentlich nicht. Aber der Code stammt ja auch nicht von mir. Das mit dem fehlenden </span> war mir aber nicht aufgefallen. Auch danke dafür. Melde mich, wenn ich es auch im PHP hinbekommen habe.
Grüße
Frank
 
Hallo Sempervivum,
habe es leider noch nicht hinbekommen. Kennst Du Dich damit aus und weißt evtl. Rat? Sonst würde ich ggf. nochmal speziell im PHP-Bereich um Hilfe bitten.
LG
Frank
 
Auf jeden Fall kann ich es versuchen. Poste doch mal einen Teststring wo das PHP, das Du oben gepostet hast, nicht funktioniert.
Was mir vorab schon auffällt: Du stellst den spitzen Klammern einen Backslash voran. Ich wüsste nicht, dass diese in Regex eine spezielle Bedeutung haben.
Den String aus deinem ersten Posting habe ich getestet und mit dem funktioniert das PHP.
Mir ist inzwischen schon aufgefallen, dass meine Regex auch einen String akzeptiert, der nur aus Whitespaces besteht, denn diese sind ja ebenfalls ungleich "<". Könnte das dein Problem verursachen?
 
Zuletzt bearbeitet:
Was mir vorab schon auffällt: Du stellst den spitzen Klammern einen Backslash voran. Ich wüsste nicht, dass diese in Regex eine spezielle Bedeutung haben.
Der backslash ist i.d.R. eine Escape-Sequenz.
Heisst: Alles was folgt "wortwörtlich" (="literal") zurückgeben.
Aber ich stimme zu:
\< ist unfug, da < (oder >) keine "Steuerungsparameter" sind
\* würde aber z.B. nach dem Stern im String suchen
 
Jein. <> Wird durchaus verwendet. Muss aber trotzdem selten mit \ geschrieben werden, da es nicht alleine auftritt
Named Capturing Group: (?P<name>...)
Macth Subpattern: \k<name>
Positiv/Negativ Lookbehind: (?<=...)
etc.
 
Zuletzt bearbeitet:
Hallo Sempervivum,
vielen Dank für Deine Hilfe. :) Nach meinem Wissen gehört an den Anfang und das Ende des Regex ein Slash. Wenn ich diese wegnehme, funktioniert es auch nicht.
Also, mein Code aus meinem ersten Beitrag funktioniert, so wie er soll (warum jetzt auch immer). Hier ist er:
PHP:
<?php
 $datei = '<a  href="file:///Users/frankpaul/Library/Mobile%20Documents/com~apple~CloudDocs/WSL_CMS/home.html"><span class="s2"><span class="s2">Ho3po5e</span></a>';
$datei = htmlentities($datei);
preg_match('/\>(.*?)<\//', html_entity_decode($datei), $matches);
echo "ERGEBNIS: ".$matches[1];
?>

"Dein" Code (<a\s+href.*>([^<]+)<.*<\/a>)funktioniert auch, allerdings bei mir nur in regex101. Wenn ich ihn dort sonderzeichencodiert ausgeben lasse und in PHP einbaue, wird ein leerer String ausgegeben. Hier der komplette Code:
PHP:
<?php   
$datei = '<a href="file:///Users/frankpaul/Library/Mobile%20Documents/com~apple~CloudDocs/WSL_CMS/home.html"><span class="s2"><span class="s2">Ho3wewewepo5e</span></a>';
$datei = htmlentities($datei);
preg_match('//<a\s+href.*>([^<]+)<.*<\/a>/gm/', html_entity_decode($datei), $matches);
echo "ERGEBNIS: ".$matches[1];
?>
Wahrscheinlich habe ich einen Fehler in meinem PHP-Code. Könntest Du mir Deinen Code mal komplett mit rein kopieren (wie ich oben)?
Vielen Dank schonmal im voraus :)
PS: Bei Whitepsaces habe ich übrigens keine Match.
 
Zuletzt bearbeitet von einem Moderator:
Nachdem ich deinen Code in Code-PHP-Tags gesetzt habe und man ihn lesen kann, fällt mir was auf.
Warum ein htmlentities() vor dem preg_match()? Das wandelt die < in HTML-Code. Dann müsstest du den Pattern anpassen, da $datei kein < und > mehr enthält sondern &lt; und &gt;

PHP:
<plaintext><?php
$datei = '<a href="file:///Users/frankpaul/Library/Mobile%20Documents/com~apple~CloudDocs/WSL_CMS/home.html"><span class="s2"><span class="s2">Ho3wewewepo5e</span></a>';
echo(htmlentities($datei));
?></plaintext>
Ausgabe und somit der String, auf den du RegEx anwenden willst
Code:
&lt;a href=&quot;file:///Users/frankpaul/Library/Mobile%20Documents/com~apple~CloudDocs/WSL_CMS/home.html&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&lt;span class=&quot;s2&quot;&gt;Ho3wewewepo5e&lt;/span&gt;&lt;/a&gt;</plaintext>

Also lass das htmentities() weg oder erst nach dem preg_match() oder passe die Patterns an, dass du nicht nach < suchst sondern nach &lt;
 
Zurück