2011-01-06 9 views
3

Hallo ist habe ich ein Beispiel CDATA hierWas die regulären Ausdruck für CDATA

<![CDATA[asd[f]]]> 

und

<tag1><![CDATA[asd[f]]]></tag1><tag2><![CDATA[asd[f]]]></tag2> 

Die CDATA regex Ich habe nicht in der Lage ist, diese

"<![CDATA["([^\]]|"]"[^\]]|"]]"[^>])*"]]>" 

zu erkennen das funktioniert nicht

Will jemand bitte geben Sie mir einen regulären Ausdruck für <![CDATA[asd[f]]]>, muss ich es verwenden in Lex/Flex

: Ich habe diese Frage beantwortet, bitte auf meine Antwort stimmen, danke.

+0

Es ist schwer zu sagen, nur geändert, wenn Sie die richtigen breckets entkommen. Auch die XML-Spezifikation sagt die erste]]> nach /s' – sln

+0

Sie wollen' '' nirgends in diesem RE verwenden. –

+1

Und ... warum nicht einfach einen XML-Parser verwenden und entweder mit einer DOM-Struktur oder einem SAX-ähnlichen Ereignisstrom arbeiten? –

Antwort

1

Dies ist die Lösung. Der Grund, warum wir einen START-STATUS verwenden müssen, ist, dass das, was immer zwischen <!CDATA[ und ]]> liegt, nicht mit anderen REGEX übereinstimmt.

%option noyywrap 
%x CDATA 

%% 
"<![CDATA[" { BEGIN CDATA; printf("Entering CDATA\n"); } 
<CDATA>([^\]]|\n)*|. { printf("In CDATA: %s\n", yytext); } 
<CDATA>"]]>" { 
    printf("End of CDATA\n"); 
    BEGIN INITIAL; 
} 

%% 
main() 
{ 
    yylex(); 
} 
0

Ich glaube, this other SO answer kann eine Hilfe sein, obwohl sie HTML-Inhalte greifen und .NET ist.

Es gibt andere Antworten mit verschiedenen Optionen für das Ergreifen von CDATA in derselben Frage.

CHAD Antwort:

<!\[CDATA\[(.*?)\]\]> 

Matching gegen:

<![CDATA[asd[f]]]> 

ruft:

asd[f] 

zu FlexRegEx sowieso nach.

+1

Versucht, dass funktioniert nicht –

+0

Versuchte alle. Kompiliert nicht in Flex –

+0

Der von Tschad scheint gut zu funktionieren, zumindest für mich. –

5

Einfach genug, es sollte sein:

<!\[CDATA\[.*?\]\]> 

Mindestens it works on regexpal.com

+0

Ja, das sollte es tun. – sln

+0

Das Hauptproblem ist, wenn ich so etwas wie dieses haben . Das obige REGEX erkennt die 2 CDATA –

+0

@ Freddy nicht, natürlich nicht, das wäre schrecklich. Wenn Sie mehrere Instanzen einer Sache finden möchten, müssen Sie Ihre Suche wiederholen. Wie Sie hier sehen können: http://tinyurl.com/2bztpjn wird es mehrere Instanzen finden, aber nicht auf einmal –

2

Das Problem ist, dass dies eher umständlich ist mit der Art von regulären Ausdrücken in lex verwendet entsprechen; wenn Sie ein System hatte die EREs unterstützt, dann würden Sie in der Lage sein, entweder zu tun:

<!\[CDATA\[(.*?)\]\]> 

oder

<!\[CDATA\[((?:[^]]|\](?!\]>))*)\]\]> 

(Die erste nutzt nicht gierige Quantoren, die zweite verwendet negative Vorschau Einschränkungen. OK, es verwendet auch nicht-erfassende Paren, aber Sie können stattdessen Captures verwenden, das ist nicht so wichtig.)

Es ist wahrscheinlich einfacher, dies zu handhaben, indem Sie eine ähnliche Strategie wie in C-style-Kommentaren behandelt werden lex, indem Sie eine Regel haben, um die st Kunst der CDATA (unter <![CDATA[) und lege den Lexer in einen separaten Zustand, den er beim Sehen ]]> verlässt, während er alle Zeichen dazwischen sammelt. This ist lehrreich zu diesem Thema (und es scheint, dass dies ein Bereich ist, wo flex und lex unterscheiden) und es deckt alle Strategien ab, die Sie ergreifen können, um diese Arbeit zu machen.

Beachten Sie, dass all diese Probleme darauf zurückzuführen sind, dass es sehr schwierig ist, eine Regel mit einfachen regulären Ausdrücken zu schreiben, die die Tatsache ausdrückt, dass ein gieriger regulärer Ausdruck nur ] entspricht, wenn nicht ]> folgt. Es ist viel einfacher zu tun, wenn Sie nur eine Zwei-Zeichen- (oder Einzelzeichen!) Ende-von-interessante-Abschnitt-Sequenz haben, weil Sie solch eine ausgeklügelte Zustandsmaschine nicht brauchen.

+0

Übrigens, die beiden obigen RE funktionieren gut mit Beispieltexten wie '< ! [CDATA [asd [f]]]> Das ist ein guter Stresstest, um zu überprüfen, ob diese Muster wirklich genau dem entsprechen, was gewünscht wird. –

+0

Ja, ich denke du verstehst mein Problem ziemlich gut. Es scheint, dass ein einzelner REGEX-Ausdruck nicht ausreicht, um alle möglichen CDATA zu erfassen. Ich hoffe also, dass mir jemand Anweisungen gibt, wie man CDATA mit flex/lex einfangen kann, wobei man vorzugsweise Yacc oder Bison vermeidet. –

+0

@Freddy: Nun, lesen Sie auf jeden Fall die Seite, die ich verlinkt habe. Es geht um das Problem der Übereinstimmung von C-Kommentaren, aber es gilt auch hier doppelt. –

0

Eine Anmerkung - eine Suche nach CDATA sollte auch Kommentare ausschließen, CDATA könnte eingebettet werden.
/<!(?:\[CDATA\[(.*?)\]\]|--.*?--|\[[A-Z][A-Z\ ]*\[.*?\]\])>/sg
Dies könnte getan werden, indem überprüft wird, ob Gruppe 1 bei jeder Übereinstimmung gültig ist, die bei einer globalen Suche zurückgegeben wird.

+0

Wie ich dies testen, scheint nicht auf regextester –

+0

@Freddy Chua zu arbeiten - Es tut, was zu tun sein angenommenes zu, so dass ich denke, es funktioniert. Versuchen Sie es zu ändern (?: – sln

0
<!\[CDATA\[\s*(?:.(?<!\]\]>)\s*)*\]\]> 

previuos answer