Regulärer Ausdruck für ein String-Literal in Flex/Lex

Lesezeit: 4 Minuten

Benutzeravatar von Thomas
Thomas

Ich experimentiere, um Flex zu lernen, und möchte Zeichenfolgenliterale abgleichen. Mein Code sieht derzeit so aus:

"\""([^\n\"\\]*(\\[.\n])*)*"\""        {/*matches string-literal*/;}

Ich habe ungefähr eine Stunde lang mit Variationen gekämpft und kann es nicht so zum Laufen bringen, wie es sollte. Ich hoffe im Wesentlichen, ein Zeichenfolgenliteral zu finden, das keine neue Zeile enthalten kann (es sei denn, es ist maskiert) und unterstützt maskierte Zeichen.

Ich schreibe wahrscheinlich nur einen schlechten regulären Ausdruck oder einen, der mit Flex nicht kompatibel ist. Bitte beraten!

  • Vielen Dank an alle! Alle Ihre Kommentare waren sehr hilfreich. Die Regex, die endlich für mich funktioniert hat, ist eine Variante derjenigen, die in der von codadict verlinkten (und von Jonathan erklärten) C-Spezifikation verwendet wird: \”(\(.|\n)|[^\\”\n])*\”

    – Thomas

    11. Januar 2010 um 4:12 Uhr

  • Da Sie Jonathans Antwort hilfreich fanden, sollten Sie erwägen, eine positive Bewertung für seine Antwort hinzuzufügen.

    – codaddict

    11. Januar 2010 um 4:17 Uhr

  • Übrigens: Nirgendwo in Ihrer Frage geben Sie an, an welchen String-Literalen der Sprache Sie interessiert sind. Es ist eine sehr gute Idee, die Sprache, nach der Sie fragen, in eines der Tags der Frage zu setzen.

    – Laurence Gonsalves

    11. Januar 2010 um 5:14 Uhr

Benutzeravatar von Jonathan Feinberg
Jonathan Feinberg

Ein String besteht aus einem Anführungszeichen

"

gefolgt von null oder mehr von entweder einem entkommenen irgendetwas

\\.

oder ein Nicht-Anführungszeichen, kein Backslash-Zeichen

[^"\\]

und schließlich ein abschließendes Zitat

"

Setzen Sie alles zusammen, und Sie haben

\"(\\.|[^"\\])*\"

Die begrenzenden Anführungszeichen werden maskiert, da es sich um Flex-Metazeichen handelt.

  • Leider funktioniert dies nicht mit dem Entkommen. Das wäre also falsch lex "\""

    – Paul Biggar

    1. August 2010 um 12:55 Uhr


  • Sie müssen “null oder mehr von einem entkommenen irgendetwas” übersehen haben?

    – Jonathan Feinberg

    2. August 2010 um 1:48 Uhr

  • Es gibt mehrere Probleme mit dieser Antwort. Erstens ist es kein gültiges Flex-Muster. Die führenden und abschließenden doppelten Anführungszeichen müssen maskiert werden, da flex sie sonst als Metazeichen behandelt. Das Muster sollte also (vielleicht) \”(\\.|[^”])*\” . Zweitens funktioniert dieses Muster immer noch nicht. Beispielsweise wird diese Eingabe falsch: “\\\\” . Drittens erfüllt es nicht die Anforderung der ursprünglichen Frage, Zeilenumbrüche zu verbieten.

    – Mayoff ausrauben

    27. Juli 2011 um 1:13 Uhr


  • Als Regex ist dies völlig korrekt. Mit Ausnahme des Newline-Dings, das durch Ersetzen leicht behoben werden kann . mit [^\n] und [^"] mit [^"\n]. Es sollte auf jeden Fall passen "\\\\" auch, da die Wiederholung dem Zitat entspricht "dann der entkommene Schrägstrich \\ dann der nächste entkommene Schrägstrich \\ dann das abschließende Zitat ". Das Muster funktioniert für mich sicherlich außerhalb des Bereichs von Flex.

    – d11wtq

    15. November 2011 um 10:38 Uhr


  • Es spielt keine Rolle, ob es außerhalb des Flex-Bereichs funktioniert. Die Frage bezog sich auf Flex. Wenn der von Flex erzeugte Lexer sieht "\\\\"foo"stimmt es mit der gesamten Eingabe überein, anstatt nur mit der "\\\\" Teil, weil die Zeichenklasse Backslashes nicht ausschließt.

    – Mayoff ausrauben

    9. Januar 2013 um 4:48 Uhr

Für eine einzelne Zeile … können Sie Folgendes verwenden:

\"([^\\\"]|\\.)*\"  {/*matches string-literal on a single line*/;}

  • Dies ist die beste Antwort hier.

    – kirbyfan64sos

    15. Januar 2016 um 17:47 Uhr


  • Sollten wir nicht sicherstellen, dass dem Anfangszitat kein Backslash vorangestellt ist (es maskiert ist) ?

    – Shrutesh Patil

    29. Januar 2020 um 20:23 Uhr

  • Wenn ihm ein umgekehrter Schrägstrich vorangestellt ist, sollte er mit keiner anderen Regel übereinstimmen und somit einen Fehler signalisieren.

    – Noob Doob

    5. März 2021 um 20:37 Uhr

Benutzeravatar von t0mm13b
t0mm13b

Wie wäre es mit einem Startzustand …

int enter_dblquotes = 0;

%x DBLQUOTES
%%

\"  { BEGIN(DBLQUOTES); enter_dblquotes++; }

<DBLQUOTES>*\" 
{ 
   if (enter_dblquotes){
       handle_this_dblquotes(yytext); 
       BEGIN(INITIAL); /* revert back to normal */
       enter_dblquotes--; 
   } 
}
         ...more rules follow...

Es war ähnlich wie dieser Effekt (flex uses %s oder %x um anzugeben, welcher Zustand erwartet wird. Wenn der Flex-Eingang ein Zitat erkennt, wechselt er in einen anderen Zustand und fährt dann mit der Lexierung fort, bis er ein anderes Zitat erreicht, in dem er in den normalen Zustand zurückkehrt.

  • @Samoz: Nicht wirklich, es wird tatsächlich in Sprachen verwendet, in denen Zeichenfolgenliterale verwendet werden. Es frisst das auf, was zwischen einem Anfangszitat und einem Endzitat steht, selbst wenn es zusätzliche Anführungszeichen enthält, daher die Verwendung von Schaltzuständen, um die Anführungszeichen zu zerkauen …

    – t0mm13b

    4. Juni 2010 um 23:39 Uhr

  • Das Flex-Handbuch enthält ein vollständiges Beispiel (in Bezug auf die Verwendung von Flex) zum Analysieren von Zeichenfolgen im C-Stil: flex.sourceforge.net/manual/Start-Conditions.html . Suchen Sie auf dieser Seite nach “Zeichenfolgen in Anführungszeichen”.

    – Mayoff ausrauben

    27. Juli 2011 um 1:22 Uhr


Fügen Sie mein Code-Snippet zum Umgang mit Zeichenfolgen in Flex ein, ich hoffe, Sie inspirieren Ihr Denken.

Verwenden Startbedingung String-Literal zu handhaben wird skalierbarer und übersichtlicher.

%x SINGLE_STRING

%%

\"                          BEGIN(SINGLE_STRING);
<SINGLE_STRING>{
  \n                        yyerror("the string misses \" to termiate before newline");
  <<EOF>>                   yyerror("the string misses \" to terminate before EOF");
  ([^\\\"]|\\.)*            {/* do your work like save in here */}
  \"                        BEGIN(INITIAL);
  .                         ;
}

Das verwenden wir darin Zolang für einzeilige Zeichenfolgenliterale mit eingebetteten Vorlagen ${...}

\"(\$\{.*\}|\\.|[^\"\\])*\"

  • Es wäre in der Lage, dies richtig abzugleichen: "Hello ${some + "world"}"

    – Þorvaldur Rúnarsson

    27. September 2018 um 0:49 Uhr

Benutzeravatar von Floern
Floern

Eine Antwort, die spät eintrifft, aber für den nächsten, der sie braucht, nützlich sein kann:

\"(([^\"]|\\\")*[^\\])?\"

  • Es wäre in der Lage, dies richtig abzugleichen: "Hello ${some + "world"}"

    – Þorvaldur Rúnarsson

    27. September 2018 um 0:49 Uhr

1412750cookie-checkRegulärer Ausdruck für ein String-Literal in Flex/Lex

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy