1

Ich bin ein Telegramm Bietet in PHP zu entwickeln, wo ich Strings zu handhaben, in denen nur einige basic HTML tag are allowed und all <, > und & Symbole, die nicht Teil eines Tags oder eine HTML sind Unternehmen müssen mit den entsprechenden HTML-Entitäten (< mit &lt;, > mit &gt; und & mit &amp;)
Beispiel stringPHP Regex negative Lookbehind variabler Länge Alternative Ausgabe

<b>bold</b>, <strong>bold</strong> 
<i>italic</i>, <em>italic</em> 
<a href="http://www.example.com/" >inline URL</a> 
<code>inline fixed-width code</code> 
<pre>pre-formatted fixed-width code block</pre> 
yes<b bad<>b> <bad& hi>;<strong >b<a< 

ersetzt ich es geschafft,zu ersetzen 0 und < mit Regex. Zum Beispiel habe ich negative Lookahead in diesem Muster verwendet <(?!(?:(?:\/?)(?:(?:b>)|(?:strong>)|(?:i>)|(?:em>)|(?:code>)|(?:pre>)|(?:a(?:[^>]+?)?>))))< Symbol loszuwerden.

Aber ich bin nicht in der Lage, ein Muster zu erstellen, um > Symbol zu ersetzen, das kein Teil eines Tags ist. PCRE unterstützt keine unbestimmten Quantoren in Look-Hintern. Obwohl es Alternativen innerhalb von Lookbehinds erlaubt, unterschiedliche Längen zu haben, erfordert es jedoch, dass jede Alternative eine feste Länge hat.

Also habe ich versucht, dieses Muster zu verwenden (noch unvollständig) (?<!(?:(?:<b)|(?:<strong)|(?:<i)|(?:<em)|(?:<code)|(?:<pre>)|(?:<a)))>, bei dem alle Alternativen Längen haben festgelegt, aber es sagt noch Compilation failed: lookbehind assertion is not fixed length

+0

War eine gute Antwort für dich Kumpel. Lassen Sie, Comeback mit einer guten Regex-Lösung, aber sehen Sie, dass Sie bereits eine kurze Regex-Lösung markiert haben, die nie funktionieren wird. Leider kann ich meine Antwort nicht löschen. Ich werde es das nächste Mal besser wissen, wenn ich deinen Namen sehe. – sln

Antwort

1

Die richtige Antwort wäre stattdessen ein DOM-Parser zu verwenden. Für eine schnelle und schmutzige (und manchmal auch schneller) Art und Weise aber, könnte man den (*SKIP)(*FAIL) Mechanismus verwenden, die PCRE Arbeitsgeräte:

<[^<>&]+>(*SKIP)(*FAIL)|[<>&]+ 

a demo on regex101.com See.


Ein komplettes PHP Freilos wäre:

<?php 
$string = <<<DATA 
<b>bold</b>, <strong>bold</strong> 
<i>italic</i>, <em>italic</em> 
<a href="http://www.example.com/" >inline URL</a> 
<code>inline fixed-width code</code> 
<pre>pre-formatted fixed-width code block</pre> 
yes<b bad<>b> <bad& hi>;<strong >b<a< 
DATA; 

$regex = '~<[^<>&]+>(*SKIP)(*FAIL)|[<>&]+~'; 
$string = preg_replace_callback($regex, 
    function($match) { 
     return htmlentities($match[0]); 
    }, 
    $string); 

echo $string; 
?> 

Welche ergibt:

<b>bold</b>, <strong>bold</strong> 
<i>italic</i>, <em>italic</em> 
<a href="http://www.example.com/" >inline URL</a> 
<code>inline fixed-width code</code> 
<pre>pre-formatted fixed-width code block</pre> 
yes&lt;b bad&lt;&gt;b&gt; &lt;bad&amp; hi&gt;;<strong >b&lt;a&lt; 

jedoch, wie schon viele Male zuvor auf Stackoverflow angegeben, sollten Sie einen Parser stattdessen verwenden, danach alle, was sie sind gemacht für.


Ein Parser Weg könnte sein:

$dom = new DOMDocument(); 
$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_NOERROR); 

echo $dom->saveHTML(); 

Allerdings ist Ihr präsentiert Schnipsel korrupt so regulären Ausdrücken ist vielleicht der einzige Weg, es zu handhaben.

+0

Danke für die Antwort. Ich habe DOM Parser versucht, aber nicht die gewünschten Ergebnisse erzielt. Kannst du mir bitte zeigen, wie ich das machen kann? – ManzoorWani

+0

@ManzoorWani: Aktualisiert, siehe das Ende der Antwort. – Jan

+0

Ja, die Snippets werden nicht erwartet, deshalb habe ich nach Regex gesucht. Wie auch immer, du hast die Idee, wie man mit Regex damit umgehen soll. Danke :) – ManzoorWani

1

Sie können legitime Sonderzeichen finden, die in solche Objekte konvertiert werden sollen.

Das große Ding ist richtig, ein Tag zu analysieren.
Haftungsausschluss - Wenn Sie es nicht tun den Weg unten, gibt es keinen Grund, auch Regex zu verwenden, wird es nicht funktionieren.Erklärt

Auf jedem Spiel der Gruppe 0 enthält entweder <,> oder &
Sie mehr hinzufügen können, die Regex an der Unterseite

Die regex
(?:(?><(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>)(*SKIP)(*FAIL)|[<>]|[&](?!(?i:[a-z]+|(?:\#(?:[0-9]+|x[0-9a-f]+)));))

sehen

(?: 
     (?>       # Atomic group 
      <        # Match tag forms and fail them with skip/fail verbs (see below) 
      (?: 
       (?: 
        (?: 
                 # Invisible content; end tag req'd 
          (       # (1 start) 
           script 
          | style 
           #| head 
          | object 
          | embed 
          | applet 
          | noframes 
          | noscript 
          | noembed 
         )        # (1 end) 
          (?: 
           \s+ 
           (?> 
            " [\S\s]*? " 
           | ' [\S\s]*? ' 
           | (?: 
             (?! />) 
             [^>] 
            )? 
           )+ 
         )? 
          \s* > 
        ) 

        [\S\s]*? </ \1 \s* 
        (?= >) 
       ) 

      | (?: /? [\w:]+ \s* /?) 
      | (?: 
        [\w:]+ 
        \s+ 
        (?: 
          " [\S\s]*? " 
         | ' [\S\s]*? ' 
         | [^>]? 
        )+ 
        \s* /? 
       ) 
      | \? [\S\s]*? \? 
      | (?: 
        ! 
        (?: 
          (?: DOCTYPE [\S\s]*?) 
         | (?: \[CDATA\[ [\S\s]*? \]\]) 
         | (?: -- [\S\s]*? --) 
         | (?: ATTLIST [\S\s]*?) 
         | (?: ENTITY [\S\s]*?) 
         | (?: ELEMENT [\S\s]*?) 
        ) 
       ) 
      ) 
      > 
    )        # End atomic group 
     (*SKIP)(*FAIL) 

    |        #or, 
     [<>]       # Angle brackets 

    |        #or, 
     [&]       # Ampersand 
     (?!       # Only if not an entity 
      (?i: 
       [a-z]+ 
      | (?: 
        \# 
        (?: 
          [0-9]+ 
         | x [0-9a-f]+ 
        ) 
       ) 
      ) 
      ;  
    ) 

     # Add more here 
)