Regex: Alle F außerhalb von HTML-Tags matchen



  • Ich brauche einen Regex, der mir alle F in einem Text matched, aber nur die, die sich außerhalb eines HTML-Tags, also außerhalb von < > befinden.

    Beispiel:
    FFF<font color="#FFEEFF">F blubb</font>f

    Die fett markierten F sollen gematched werden.

    Was ich u.a. versucht habe, war dem String ein > an den Anfang und ein < an das Ende hinzuzufügen, damit ich dann nach >.*F.*< suchen kann, hat aber auch nicht geklappt 😞

    Ich probier schon zwei Stunden rum, bekomme es aber einfach nicht hin!

    Vielen Dank im Voraus!



  • Für Perl-Sprecher ein Kinderspiel 😃

    #!/usr/bin/perl
    my $var = 'FFF<font color="#FFEEFF">F blubb</font>f';
    while($var =~ /[b]F(?![\w ="#]*>)[/b]/gi) {
    	print "$`  <$&>  $'\n";
    }
    

    Ausgabe:

    <F>  FF<font color="#FFEEFF">F blubb</font>f
    F  <F>  F<font color="#FFEEFF">F blubb</font>f
    FF  <F>  <font color="#FFEEFF">F blubb</font>f
    FFF<font color="#FFEEFF">  <F>   blubb</font>f
    FFF<font color="#FFEEFF">F blubb</font>  <f>
    

    Sollte sein, was du suchst, oder?



  • Er wollte aber nur alle Fs außerhalb spitzer Klammern, also "FFF" als Rückgabemenge. Hab ich was falsch verstanden?



  • F98 schrieb:

    Er wollte aber nur alle Fs außerhalb spitzer Klammern, also "FFF" als Rückgabemenge. Hab ich was falsch verstanden?

    Welche Fs gefragt sind, hat er ja explizit gesagt. Wenn die "FFF" als ein Treffer gelten sollen, hätte er einfach ein "+" dazu machen müssen. Das hätte selbst ein Anfänger geschafft, denke ich 😉

    #!/usr/bin/perl 
    my $var = 'FFF<font color="#FFEEFF">F blubb</font>f'; 
    while($var =~ /F[b]+[/b](?![\w ="#]*>)/gi) { 
        print "$`  <$&>  $'\n"; 
    }
    
    <FFF>  <font color="#FFEEFF">F blubb</font>f
    FFF<font color="#FFEEFF">  <F>   blubb</font>f
    FFF<font color="#FFEEFF">F blubb</font>  <f>
    


  • minhen schrieb:

    Für Perl-Sprecher ein Kinderspiel 😃

    #!/usr/bin/perl
    my $var = 'FFF<font color="#FFEEFF">F blubb</font>f';
    while($var =~ /[b]F(?![\w ="#]*>)[/b]/gi) {
    	print "$`  <$&>  $'\n";
    }
    

    Ausgabe:

    <F>  FF<font color="#FFEEFF">F blubb</font>f
    F  <F>  F<font color="#FFEEFF">F blubb</font>f
    FF  <F>  <font color="#FFEEFF">F blubb</font>f
    FFF<font color="#FFEEFF">  <F>   blubb</font>f
    FFF<font color="#FFEEFF">F blubb</font>  <f>
    

    Sollte sein, was du suchst, oder?

    Ja, das ist so ziemlich was ich wollte. Kannst mir den Regex noch erklären, kapier das so noch nicht ganz...



  • Hey!

    Habs mir nochmal angesehen und es funkt jetzt soweit! 🙂
    Aber was noch Probleme macht, ist wenn jetzt z.B. sowas im Suchstring steht: FFF fff asdf <font style="background-color: green; font-weight: bold;">ff F das </font> do

    Hab versucht das Problem zu lösen, indem ich einfach die zusätzlichen Zeichen, die nun Möglich wären, der Charakterklasse hinzufüge, das klappte aber auch nicht:

    /F(?![\w ="#;:]*>)/i
    

    Achja, was ich oben nicht erwähnt habe, ich nutze den Regex in PHP mit der Funktion preg_replace(). Dort gibt es den Modifier g nicht, deshalb hab ich ihn einfach weggelassen. Wäre der für die korrekte Funktionsweise ausschlaggebend?



  • k, jetzt hätte ich da was:

    $such = preg_replace('/('.$keyword.')(?![\w| |=|"|\'|#|;|:|\-]*>)/i', '<font style="background-color: yellow;">$1</font>', $such);
    

    Das funkt soweit...
    Was mich jetzt aber interessieren würde, warum musste ich alle Zeichen, die vor der Spitzklammer kommen dürfen, damit er nicht matched, als Alternative mit | definieren, das hast du nicht machen müssen?
    Und warum klappt der Regex als äquivalent nicht:
    /('.$keyword.')(?!.*>)/iU

    😕

    So richtig verstehe ich doch noch nix, erklär mir die Funktionweise bitte einfach mal. 😉

    thx.



  • Reggi schrieb:

    Hab versucht das Problem zu lösen, indem ich einfach die zusätzlichen Zeichen, die nun Möglich wären, der Charakterklasse hinzufüge, das klappte aber auch nicht

    Es klappt schon. Du hast nur das "-" vergessen: F(?![\w ="#;:-]*>) 😉

    Dort gibt es den Modifier g nicht, deshalb hab ich ihn einfach weggelassen. Wäre der für die korrekte Funktionsweise ausschlaggebend?

    "g" führt lediglich eine globale Suche auf den gesamte String aus. D.h. versucht so oft wie möglich zu matchen. Wenn das deine PHP-Funktion automatisch schon macht, kannst ihn dir natürlich sparen.
    Der Hintergrund bei Perl ist einfach der, dass man dort if(/REGEX/) schreiben kann. Und da ist es natürlich Zeitverschwendung alle Treffer zu suchen, denn der erste reicht schon.

    Reggi schrieb:

    Und warum klappt der Regex als äquivalent nicht:
    /('.$keyword.')(?!.*>)/iU

    Weil du damit ja alle Zeichen erlaubst. Also auch "<" und ">". Wenn du die erlaubten Zeichen nicht angeben willst, so musst du die nicht erlaubten zumindest ausschließen: F(?![^<>]*>)

    Reggi schrieb:

    So richtig verstehe ich doch noch nix, erklär mir die Funktionweise bitte einfach mal. 😉

    (?!Muster) ist einfach der negative Lookahead-Operator und besagt, dass Muster NICHT folgen darf. (?=) wäre das positive Gegenstück, welches besagt, dass das Muster folgen muss. Das ist auch schon das ganze Geheimnis 🙂



  • Dann wäre ja alles geklärt. 😉

    Danke für deine Hilfe! 🙂



  • Dieser Thread wurde von Moderator/in Marc++us aus dem Forum Themen rund um den PC in das Forum Webzeugs verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • hi kann man mit regex html tags aus einem string entfernen? wenn könnte jemand zeigen wie?

    cu


Log in to reply