Regulärer Ausdruck, um HTML-Zeichen unter Einhaltung von CDATA zu umgehen

8

Ich habe ein Content-Management-System geschrieben, das einen serverseitigen regulären Ausdruck verwendet, um Ampersands in der Seitenantwort vor dem Senden an den Browser des Clients zu entkommen. Der reguläre Ausdruck berücksichtigt die Und-Zeichen, die bereits maskiert wurden oder Teil einer HTML-Entität sind. Zum Beispiel das Folgende:

%Vor%

wird geändert:

%Vor%

(Nur der erste & ist modifiziert.) Hier ist der reguläre Ausdruck, der von einem Rails-Helfer übernommen und modifiziert wurde:

%Vor%

Das funktioniert zwar gut, hat aber ein Problem. Der reguläre Ausdruck kennt keine <![CDATA[ oder ]]> , die die nichtskapierten Ampersands umgeben könnten. Dies ist erforderlich, damit eingebettetes JavaScript unberührt bleibt. Zum Beispiel:

%Vor%

wird leider so dargestellt:

%Vor%

was die JavaScript-Engines natürlich nicht verstehen.

Meine Frage ist: Gibt es eine Möglichkeit, den regulären Ausdruck so zu ändern, dass er genau so funktioniert, wie er es jetzt tut, mit der Ausnahme, dass der Text in einem CDATA-Bereich unberührt bleibt?

Da der reguläre Ausdruck nicht so einfach ist, könnte diese Frage leichter zu beantworten sein: Ist es möglich, einen regulären Ausdruck zu schreiben, der alle Buchstaben in einen Punkt ändert, ausgenommen die Buchstaben zwischen ' < ' und ein Code%'? Zum Beispiel eine, die > in "some <words> are < safe! >" ändern würde?

    
Nick 20.01.2009, 19:52
quelle

5 Antworten

7

Sie haben danach gefragt! : D

%Vor%

Die erste Zeile ist Ihre ursprüngliche Regex. Die Vorausschau stimmt überein, wenn eine CDATA-Schlusssequenz ( ]]> ) weiter vorne liegt, es sei denn, es gibt eine Eröffnungssequenz ( <!CDATA[ ) zwischen hier und dort. Angenommen, das Dokument ist minimal gut gebildet, sollte dies bedeuten, dass die aktuelle Position innerhalb eines CDATA-Abschnitts liegt.

Hoppla, ich hatte das rückwärts: Mit positivem Lookahead habe ich "nackte" Und-Zeichen nur innerhalb von CDATA-Abschnitten gefunden. Ich habe es in ein negatives Lookahead geändert, jetzt funktioniert es richtig.

Übrigens funktioniert diese Regex in RegexBuddy im Ruby-Modus, aber nicht auf der Rubulusseite . Ich vermute, dass Rubular eine ältere Version von Ruby mit weniger leistungsstarker Regex-Unterstützung verwendet; kann das jemand bestätigen? (Wie Sie vielleicht erraten haben, bin ich kein Ruby-Programmierer.)

BEARBEITEN: Das Problem bei Rubular war, dass ich 's' als Modifizierer verwendete (dot-matches-everything), aber Ruby verwendet 'm' dafür.

    
Alan Moore 21.01.2009, 22:49
quelle
3

Verwenden Sie keine regulären Ausdrücke dafür. Es ist eine schreckliche, schreckliche Idee. Stattdessen kodieren Sie einfach alles, was Sie ausgeben, das ein Zeichen enthalten könnte. So:

%Vor%     
Evan Fosmark 21.01.2009 03:28
quelle
1

Das hat funktioniert! Bei Rubular musste ich die Optionen von /xs auf /m ändern (und ich entfernte den Leerraum, der die beiden Teile der Regex trennt wie du es oben gezeigt hast).

Sie können diesen regulären Ausdruck zusammen mit einer Beispielzeichenfolge in Ссылка sehen.

Falls der Permalink Rubular nicht wirklich permanent ist, hier ist was ich für den regulären Ausdruck eingegeben habe:

%Vor%

Und hier ist die Testzeichenfolge:

%Vor%

Nur zwei kaufmännische Unds passen zusammen - die a & b oben und die a & b unten. Ampersands sind bereits als &amp; und alle Ampersands (mit oder ohne Escape-Zeichen) zwischen <![CDATA[ und ]]> wurden nicht gefunden.

Also, mein endgültiger Code ist jetzt folgender:

%Vor%

Vielen Dank Alan. Genau das habe ich gebraucht.

    
Nick 22.01.2009 18:43
quelle
0

ich etwas ähnliches hier getan haben:
Der beste Weg, zu kodieren Textdaten für XML

Zum Glück, in meinem Fall CDATA war kein Problem.

Was ist ein Problem ist, dass man vorsichtig sein, dass der Ausdruck nicht gierig ist, oder Sie werden mit etwas am Ende wie folgt:

.... <words> are < safe! >

    
Joel Coehoorn 20.01.2009 20:09
quelle
0

Ich bezweifle ernsthaft, dass das, was Sie zu erreichen versuchen, etwas ist, was Sie tun können, wenn Sie nur einen regulären Ausdruck verwenden. Regexps sind notorisch schlecht darin, Nesting richtig zu handhaben.

Sie werden wahrscheinlich besser einen XML-Parser verwenden und nicht den CDATA-Inhalt umgehen.

    
pilif 20.01.2009 22:00
quelle

Tags und Links