Saitenliteral

A Saitenliteral oder Anonyme Zeichenfolge[1] ist eine Art von Art von wörtlich für die Darstellung von a Saite Wert in der Quellcode von a Computer Programm. In modern Programmierung Sprachen, dies ist normalerweise eine zitierte Abfolge von Zeichen (formal "Klammern"), wie in x = "foo", wo "Foo" ist eine Zeichenfolge wörtlich mit Wert Foo - Die Zitate sind nicht Teil des Wertes, und man muss eine Methode wie z. Fluchtsequenzen Um das Problem von zu vermeiden Grenzkollision und erlauben das Grenzwerte selbst in eine Schnur eingebettet zu sein. Es gibt jedoch zahlreiche alternative Notationen für die Angabe von String -Literalen, insbesondere kompliziertere Fälle, und die genaue Notation hängt von der Person ab Programmiersprache fraglich. Trotzdem gibt es allgemeine Richtlinien, denen die meisten modernen Programmiersprachen folgen.

Syntax

Klammern

Die meisten modernen Programmiersprachen verwenden Bracket Grenzwerte (Auch ausgeglichene Grenzwerte) String -Literale angeben. Doppelte Zitate sind die am häufigsten verwendeten Zitat -Abgrenzer:

 "Hi!"

Eine leere Zeichenfolge wird buchstäblich von zwei Zitaten geschrieben, ohne dass ein Zeichen dazwischen ist:

 "" "

Einige Sprachen erlauben oder mandatieren die Verwendung einzelner Zitate anstelle von doppelten Zitaten (die Zeichenfolge muss mit der gleichen Art von Anführungszeichen beginnen und enden, und die Art der Anführungszeichen kann eine geringfügige Semantik ergeben oder nicht):

 'Hi!'

Diese Anführungszeichen sind ungepaart (Der gleiche Charakter wird als Opener und als näher verwendet), was ein Kater aus dem ist Schreibmaschine Technologie, die der Vorläufer der frühesten Computer- und Ausgabegeräte war.

Bezüglich Reguläre AusdrückeEine grundlegende zitierte String -Literal wird gegeben als:

"[^"]*"

Dies bedeutet, dass ein Streicherliteral als: Ein Zitat, gefolgt von Null, Eins oder mehr Nichtquote, gefolgt von einem Zitat. In der Praxis wird dies oft durch Flucht, andere Abgrenzer und Ausschluss von Neulinen kompliziert.

Gepaarte Grenzwerte

Eine Reihe von Sprachen sorgt für gepaarte Abgrenzer, bei denen die Öffnungs- und Schließungsgrenzwerte unterschiedlich sind. Diese erlauben auch oft verschachtelte Saiten, sodass Abgrenzer eingebettet werden können, solange sie gepaart sind, aber dennoch zu einer Trennzeichenkollision zum Einbetten eines ungepaarten Abschlusses. Beispiele beinhalten PostScript, was Klammern verwendet, wie in (Der schnelle braune Fuchs)) und M4, was das verwendet Backtick (`) als Startträger und der Apostroph (') Als Endtrainiter. Tcl Ermöglicht sowohl Zitate (für interpolierte Zeichenfolgen) als auch Klammern (für rohe Zeichenfolgen) wie in "Der schnelle braune Fuchs" oder {Der schnelle braune Fuchs}}; Dies ergibt sich aus den einzelnen Zitaten in Unix -Shells und der Verwendung von Zahnspangen in C Für zusammengesetzte Aussagen, da die Codeblöcke in TCL syntaktisch gleich sind wie String -Literale -, dass die Abgrenzer gepaart sind, ist es unerlässlich, dass dies machbar ist.

Das Unicode Der Charaktersatz umfasst gepaarte (separate Öffnungs- und Schließen) Versionen sowohl einzelner als auch doppelter Zitate:

 "Hi!" "Hallo da!" "Hallo da!" "Hallo!"

Diese werden jedoch selten verwendet, da viele Programmiersprachen sie nicht registrieren (eine Ausnahme sind die gepaarten doppelten Zitate, die in verwendet werden können Visual Basic .net). Unentgepaarte Markierungen werden für die Kompatibilität bevorzugt, da sie leichter auf einer Vielzahl von Tastaturen eintippen können. Selbst in Sprachen, in denen sie zugelassen sind, verbieten viele Projekte ihre Verwendung für den Quellcode.

Whitespace -Grenzwerte

String -Literale könnten von Newlines beendet werden.

Ein Beispiel ist Mediawiki Vorlagenparameter.

 {{{Navbox | name = nulls | title = [[wikt: null | nulls]] in [[computer]]}}

Es kann eine spezielle Syntax für Multi-Line-Zeichenfolgen geben.

Im Yaml, String -Literale können durch die relative Positionierung von angegeben werden Whitespace und Eindrückung.

  - Titel: Ein Beispiel für eine Multi-Line-Zeichenfolge in YAML  Karosserie : |  Dies ist eine Multi-Line-Zeichenfolge.  "Spezielle" Metacharacter können  erscheinen hier. Das Ausmaß dieser Zeichenfolge ist  dargestellt durch Eindrückung. 

Keine Grenzwerte

Einige Programmiersprachen wie Perl und PHP erlauben String -Literale ohne Grenzwerte in einigen Kontexten. Zum Beispiel im folgenden Perl -Programm, rot, grün, und blau sind String -Literale, sind aber nicht geeignet:

%Karte = (rot => 0x00f, blau => 0x0f0, grün => 0xf00); 

Perl behandelt in den meisten Kontexten nicht reservierte Sequenzen von alphanumerischen Zeichen als String-Literale. Beispielsweise sind die folgenden zwei Perllinien gleichwertig:

$ y = "x"; $ y = x; 

Deklarative Notation

Im Original Forran Programmiersprache (zum Beispiel) wurden String-Literale in so genannter Abschluss geschrieben Hollerith Notation, wo eine Dezimalzahl der Anzahl der Zeichen des Buchstabens H und dann der Zeichen der Zeichenfolge folgte:

35Han Beispiel Hollerith Saite wörtlich 

Dieser deklarative Notationsstil steht im Gegensatz zu einer Klammerung Abgrenzer Zitieren, da es nicht die Verwendung von ausgewogenen "Klammern" -Prafts auf beiden Seiten der Zeichenfolge erfordert.

Vorteile:

  • eliminiert die Such Suche (für den Trennzeichen) und erfordert daher erheblich weniger Überkopf
  • vermeidet das Problem von Grenzkollision
  • ermöglicht die Aufnahme von Metacharaccters Das könnte sonst als Befehle verwechselt werden
  • Kann zur sehr effektiven Datenkomprimierung von einfachen Textzeichenfolgen verwendet werden

Nachteile:

  • Diese Art von Notation ist fehleranfällig, wenn sie als manueller Eintrag von verwendet werden Programmierer
  • Bei Multi -Byte -Codierungen ist eine besondere Sorgfalt erforderlich

Dies ist jedoch kein Nachteil, wenn das Präfix von einem Algorithmus generiert wird, wie es höchstwahrscheinlich der Fall ist.

Konstruktorfunktionen

C ++ hat zwei Stringstile, eine von C geerbt (Grenzwerte durch ") und je sicherer std :: string in der C ++ - Standardbibliothek. Das std :: string Die Klasse wird häufig auf die gleiche Weise verwendet, wie ein Streichliteral in anderen Sprachen verwendet wird, und wird häufig zu C-Saiten im C-Stil für seine größere Flexibilität und Sicherheit bevorzugt. Aber es kommt mit einer Leistungsstrafe für String -Literale wie std :: string Zuletzt normalerweise den Speicher dynamisch und muss die String-Streichelstraße im C-Stil zur Laufzeit kopieren.

Vor C ++ 11 gab es keine buchstäbliche für C ++ - Strings (C ++ 11 erlaubt "Dies ist eine c ++ String" s "s" mit dem s Am Ende des wörtlichen) wurde beispielsweise die normale Konstruktorsyntax verwendet:

  • std :: string str = "Initializer -Syntax";
  • std :: string str ("Konvertieren der Konstruktorsyntax");
  • std :: string str = string ("explizite Konstruktorsyntax");

alle haben die gleiche Interpretation. Da C ++ 11 auch eine neue Konstruktorsyntax gibt:

  • std :: string str {"Uniform Initializer Syntax"};
  • auto str = "constexpr literaler Syntax" S;

Grenzkollision

Wenn man bei der Verwendung des Zitierens den Trennzeichen selbst in einem Saitenliteral darstellen möchte, geht man auf das Problem von Grenzkollision. Wenn der Trennzeichen beispielsweise ein doppeltes Zitat ist, kann man nicht einfach ein doppeltes Zitat selbst vom Literal darstellen "" " Da das zweite Zitat als Ende des String -Literales interpretiert wird, nicht als Wert der Zeichenfolge, und in ähnlicher Weise kann man nicht schreiben "Das ist" in Zitaten ", aber ungültig." Wie der mittlere zitierte Teil stattdessen als außerhalb von Zitaten interpretiert wird. Es gibt verschiedene Lösungen, von denen der allgemeinste Zwecke Fluchtsequenzen verwendet, wie z. "\" " oder "Das ist \" in Zitaten "und ordnungsgemäß entkommen."Aber es gibt viele andere Lösungen.

Gepaarte Zitate wie Zahnspangen in TCL erlauben verschachtelte Zeichenfolgen, wie z. {foo {bar} zork} Lösen Sie jedoch nicht sonst das Problem der Trennzeichenkollision, da ein unausgeglichener Abschluss nicht einfach einbezogen werden kann, wie in {}}.

Verdoppelung

Eine Reihe von Sprachen, einschließlich Pascal, BASIC, DCL, Smalltalk, Sql, J, und Forranvermeiden Verdoppelung Auf den Anführungszeichen, die Teil des String -Literales selbst sein sollen:

  'Diese Pascal -Zeichenfolge'' 'Enthält zwei Apostrophen'' '' 
  "Ich sagte:" "Kannst du mich hören?" "" 

Dual Zitieren

Einige Sprachen, wie z. Forran, Modula-2, JavaScript, Python, und Php erlauben Sie mehr als einen Zitat des Trennzeichens; Bei zwei möglichen Abgrenzern wird dies als bezeichnet als Dual Zitieren. In der Regel besteht dies darin, dass der Programmierer entweder einzelne Zitate oder doppelte Zitate austauschbar verwenden - jedes wörtliche muss das eine oder andere verwenden.

  "Das ist Johns Apfel."  "Ich sagte:" Kannst du mich hören? " 

Dies erlaubt jedoch nicht, dass ein einzelnes wörtliches mit beiden Abgrenzern darin besteht. Dies kann durch Verwendung mehrerer Literale und Verwendung String-Verkettung:

  "Ich sagte:" Das ist " + "Johns" + ' Apfel."' 

Python hat String buchstäbliche VerkettungDaher werden aufeinanderfolgende Streicherliterale auch ohne Operator verkettet, sodass dies reduziert werden kann:

  "Ich sagte:" Das ist ""Johns"' Apfel."' 

D Unterstützt einige Zitat -Grenzwerte, mit solchen Saiten beginnen mit q"[ und enden mit ] " oder ähnlich für ein anderes Trennzeichen (eine von () <> {} oder []). D unterstützt hier auch Strings im Dokumentstil über ähnliche Syntax.

In einigen Programmiersprachen, wie z. Sch und PerlEs gibt verschiedene Abgrenzer, die unterschiedlich behandelt werden, wie z. sehen verschiedene Arten von Saiten, unter.

Mehrfachzitieren

Eine weitere Erweiterung ist die Verwendung von Mehrfachzitieren, was es dem Autor ermöglicht, auszuwählen, welche Zeichen die Grenzen eines String -Literales angeben sollten.

Zum Beispiel in Perl:

qq^Ich sagte: "Kannst du mich hören?"^ qq@Ich sagte: "Kannst du mich hören?"@ qq§i sagte: "Kannst du mich hören?" § 

Alle erzeugen das gewünschte Ergebnis. Obwohl diese Notation flexibler ist, unterstützen nur wenige Sprachen sie; anders als Perl, Rubin (beeinflusst von Perl) und C ++ 11 Unterstützen Sie diese auch. In C ++ 11 können rohe Saiten verschiedene Grenzwerte haben, beginnend mit R "Trennzeichen ( und enden mit ) Abgrenzer ". Der Trennzeichen kann von null bis 16 Zeichen lang sein und enthalten jedes Mitglied des grundlegenden Quellzeichensatzes mit Ausnahme von Whitespace -Zeichen, Klammern oder Backslash. Eine Variante mehrerer Zitieren ist die Verwendung von Hier Dokument-Stil Strings.

LUA (ab 5.1) bietet eine begrenzte Form von mehreren Zitaten, insbesondere um die Verhinderung langer Kommentare oder eingebetteter Zeichenfolgen zu ermöglichen. Normalerweise verwendet man [[ und ]] Um die wörtlichen Zeichenfolgen abzugrenzen (anfängliche neue Linie, ansonsten roh), können die Öffnungsklammern jedoch eine beliebige Anzahl von gleichen Zeichen enthalten, und das Schließen der Klammern mit der gleichen Anzahl von Schildern schließt die Zeichenfolge. Zum Beispiel:

lokal ls = [= [ Diese Notation kann für Windows -Pfade verwendet werden:  Lokaler Path = [C: \ Windows \ Schriftarten]] ] =]] 

Multiple Zitieren sind besonders nützlich mit Reguläre Ausdrücke Das enthält übliche Grenzwerte wie Zitate, da dies vermeidet, ihnen zu entkommen. Ein frühes Beispiel ist sed, wo im Substitutionskommando S/Regex/Ersatz/ Der Standard -Schrägstrich / Abgrenzer können durch einen anderen Charakter ersetzt werden, wie in S, Regex, Ersatz, .

Konstruktorfunktionen

Eine andere Option, die in modernen Sprachen selten verwendet wird, besteht darin, eine Funktion zu verwenden, um eine Zeichenfolge zu konstruieren, anstatt sie über ein wörtliches zu repräsentieren. Dies wird im Allgemeinen in modernen Sprachen im Allgemeinen nicht verwendet, da die Berechnung zur Laufzeit und nicht zur Analysezeit durchgeführt wird.

Zum Beispiel frühe Formen von BASIC enthielt keine Fluchtsequenzen oder andere hier aufgeführte Problemumgehungen, und daher musste man die verwenden, um die zu verwenden Chr $ Funktion, die eine Zeichenfolge zurückgibt, die das Zeichen enthält, das seinem Argument entspricht. Im ASCII Die Anführungszeichen hat den Wert 34, um eine Zeichenfolge mit Zitaten auf einem ASCII -System darzustellen, das man schreiben würde

"Ich sagte, " + Chr $(34) + "Können Sie mich hören?" + Chr $(34) 

In C ist eine ähnliche Einrichtung über verfügbar Sprintf und die %c Formatspezifizierer "Charakter", obwohl dies in Gegenwart anderer Problemumgehungen im Allgemeinen nicht verwendet wird:

Sprintf("Das sind %cin Quotes. %C", 34, 34); 

Diese Konstruktorfunktionen können auch verwendet werden, um nicht druckende Zeichen darzustellen, aber stattdessen werden Fluchtsequenzen verwendet. Eine ähnliche Technik kann in C ++ mit dem verwendet werden std :: string Stringungsoperator.

Fluchtsequenzen

Escape -Sequenzen sind eine allgemeine Technik zur Darstellung von Charakteren, die ansonsten direkt zu repräsentieren, einschließlich Grenzwerfern, nicht druckenden Zeichen (wie Backpaces), Newlines und Whitespace -Zeichen (die ansonsten visuell nicht zu unterscheiden sind) und haben eine lange Geschichte. Sie werden dementsprechend in String -Literalen weit verbreitet, und es wird bekannt gegeben Flucht.

Ein Zeichen wird als Präfix ausgewählt, um Codierungen für Zeichen zu geben, die schwierig oder unmöglich sind, direkt einzuschließen. Am häufigsten ist das Backslash; Zusätzlich zu anderen Zeichen ist ein wichtiger Punkt, dass Backslash selbst als Doppel -Backslash kodiert werden kann \\ und für abgrenzte Saiten kann der Trennzeichen selbst durch Flucht kodiert werden \ " für ". Ein regelmäßiger Ausdruck für solche entkommenen Saiten kann wie folgt angegeben werden, wie in der gefundenen Ansi c Spezifikation:[2][a]

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

bedeutet "ein Zitat; gefolgt von null oder mehr entweder einem entkommenen Charakter (Backslash, gefolgt von etwas, möglicherweise Backslash oder Zitat) oder einem Nicht-Ess-, Nicht-Quote-Charakter; enden in einem Zitat"-das einzige Problem ist die Auswahl des Beenden von Zitat aus einem Zitat, dem ein Backslash vorangestellt ist, der selbst entkommen kann. Mehrere Zeichen können dem Backslash folgen, z. \ Uffffabhängig vom Fluchtschema.

Eine entkommene Saite muss dann selbst sein lexikalisch analysiertUmwandlung der entkommenen Zeichenfolge in die nicht entsandte Zeichenfolge, die sie darstellt. Dies geschieht während der Bewertungsphase des gesamten Lexens der Computersprache: Der Bewerter des Lexer der Gesamtsprache führt seinen eigenen Lexer für entkommene String -Literale aus.

Unter anderem muss es möglich sein, das Zeichen zu codieren, das normalerweise die String -Konstante beendet, und es muss eine Möglichkeit geben, das Fluchtzeichen selbst anzugeben. Escape -Sequenzen sind nicht immer hübsch oder einfach zu bedienen, so dass viele Compiler auch andere Möglichkeiten zur Lösung der gemeinsamen Probleme bieten. Escape -Sequenzen lösen jedoch jedes Trennzeichenproblem und die meisten Compiler interpretieren Fluchtsequenzen. Wenn sich ein Fluchtzeichen in einem String -Literal befindet, bedeutet dies "Dies ist der Beginn der Escape -Sequenz". Jede Fluchtsequenz gibt ein Zeichen an, das direkt in die Zeichenfolge platziert werden soll. Die tatsächliche Anzahl der in einer Escape -Sequenz erforderlichen Zeichen variiert. Der Escape -Charakter befindet sich oben/links in der Tastatur, aber der Editor übersetzt es, daher kann er nicht direkt in eine Zeichenfolge erfasst werden. Der Backslash wird verwendet, um das Fluchtzeichen in einem Streichliteral darzustellen.

Viele Sprachen unterstützen die Verwendung von Metacharaccters Innenliterale. Metacharacter haben je nach Kontext und Sprache unterschiedliche Interpretationen, sind jedoch im Allgemeinen eine Art „Verarbeitungsbefehl“ zur Darstellung von Druck- oder nicht druckenden Zeichen.

Zum Beispiel in a C String Literal, wenn der Backslash von einem Buchstaben wie "B", "N" oder "T" folgt, ist dies ein nicht gedruckter Ausdruck Rücktaste, Neue Zeile oder Tab Charakter jeweils. Oder wenn der Backslash 1-3 folgt Oktal Ziffern, dann wird diese Sequenz so interpretiert, dass sie das willkürliche Zeichen mit dem angegebenen darstellt ASCII Code. Dies wurde später erweitert, um moderner zuzulassen hexadezimal Zeichencode -Notation:

"Ich sagte,\ t \ t \ x22can hörst du mich?\ x22 \ n" 
Fluchtabfolge Unicode Buchstäbliche Zeichen in String eingelegt
\0 U+0000 Nullcharakter[3][4]
(Typischerweise als Sonderfall von \ ooo Octal Notation)
\a U+0007 Alarm[5][6]
\b U+0008 Rücktaste[5]
\f U+000C Formfutter[5]
\n U+000A Zeilenvorschub[5] (oder Newline in POSIX)
\r U+000D Kutschenrückkehr[5] (oder Newline in Mac OS 9 und früher)
\t U+0009 Horizontale Registerkarte[5]
\ v U+000B vertikale Registerkarte[5]
\ e U+001b Escape-Zeichen[6] (GCC,[7] Klang und tcc))
\ u #### U+#### 16-Bit Unicode Charakter, bei dem #### vier Sechskantigstellungen sind[4]
\ U ######## U+###### 32-Bit-Unicode-Zeichen, wobei ####### acht Sechskantigstellen sind (Unicode-Zeichenraum ist derzeit nur 21 Bit breit, sodass die ersten beiden Sechskantigstellen immer Null sind)
\ u {######}} U+###### 21-Bit-Unicode-Zeichen, wobei ###### eine variable Anzahl von Sechskantigstellen ist
\x## U+00 ## 8-Bit-Charakterspezifikation, bei der # eine Sechskantendifferung ist[5]
\ ooo U+0 ### 8-Bit-Charakterspezifikation, bei der O eine Oktalendiffer ist[5]
\ " U+0022 Doppelzitat (")[5]
\ & Nicht-Charakter, das verwendet wird, um numerische Flucht in Haskell abzugrenzen[3]
\ ' U+0027 einzelnes Zitat (')[5]
\\ U+005c Backslash (\)[5]
\? U+003f Fragezeichen (?)[5]

HINWEIS: Nicht alle Sequenzen in der Liste werden von allen Parsers unterstützt, und es können andere Escape -Sequenzen enthalten, die nicht in der Liste enthalten sind.

Verschachtelte Flucht

Wenn der Code in einer Programmiersprache in eine andere eingebettet ist, erfordern eingebettete Zeichenfolgen möglicherweise mehrere Entkommensstufen. Dies ist besonders häufig in regelmäßigen Ausdrücken und SQL -Abfragen in anderen Sprachen oder in anderen Sprachen in Shell -Skripten vorhanden. Diese Doppelaufnahme ist oft schwer zu lesen und zu verzeichnen.

Eine falsche Zitat von verschachtelten Zeichenfolgen kann eine Sicherheitsanfälligkeit darstellen. Die Verwendung nicht vertrauenswürdiger Daten, wie in Datenfeldern einer SQL -Abfrage, sollten verwendet werden Vorbereitete Aussagen zu verhindern a Codeinjektion Attacke. Im Php 2 bis 5.3 gab es eine Funktion namens namens Magische Zitate die automatisch Strings (aus Bequemlichkeit und Sicherheit) entging, wurde jedoch aufgrund von Problemen aus Version 5.4 entfernt.

Rohe Saiten

Einige Sprachen bieten eine Methode zur Angabe, dass ein wörtliches ohne sprachspezifische Interpretation verarbeitet werden soll. Dies vermeidet die Notwendigkeit einer Flucht und liefert lesbarere Saiten.

Rohe Saiten sind besonders nützlich, wenn ein gemeinsamer Charakter entkommen muss, insbesondere in regulären Ausdrücken (als Streichliterale verschachtelt), wo Backslash \ wird weit verbreitet und in DOS/Windows Wege, wo Backslash als Pfadabscheider verwendet wird. Die Fülle von Backslashes ist als bekannt als als Lieger Zahnstocher -Syndromund kann durch Verwendung von rohen Zeichenfolgen reduziert werden. Vergleichen Sie entkommene und rohe Pfadnamen in C#:

 "Der Windows -Pfad ist c: \\ foo \\ bar \\ baz \\"  @"Der Windows -Pfad ist C: \ foo \ bar \ baz \" 

Extreme Beispiele treten auf, wenn diese kombiniert werden - Einheitliche Namenskonvention Pfade beginnen mit \\und so beginnt ein entkommener regulärer Ausdruck, der einem UNC -Namen entspricht, mit 8 Backslashes, "\\\\\\\\\", weil sie der Saite und dem regulären Ausdruck entkommen müssen. Die Verwendung von rohen Saiten reduziert dies auf 4 (entkommen im regulären Ausdruck), wie in C# @"\\\\".

In XML -Dokumenten, CDATA Abschnitte ermöglichen die Verwendung von Zeichen wie & und <ohne einen XML -Parser, der versucht, sie als Teil der Struktur des Dokuments selbst zu interpretieren. Dies kann nützlich sein, wenn Sie wörtliche Text- und Skriptcode einbeziehen, um das Dokument aufrechtzuerhalten gut geformt.

 

Multiline -Streichliterale

In vielen Sprachen können String -Literale wörtliche Neulinen enthalten, die mehrere Zeilen umfassen. Alternativ können Newlines entkommen, meistens als \n. Zum Beispiel:

Echo 'Foo Bar' 

und

Echo -e "Foo \ nbar" 

sind beide gültige Bash, produzieren:

Foo Bar

Zu den Sprachen, die wörtliche Neulinen ermöglichen, gehören Bash, Lua, Perl, PHP, R und TCL. In einigen anderen Sprachen können String -Literale keine Neulinien enthalten.

Zwei Themen mit Multiline -Streicher -Literalen sind führend und nachverfolgen. Wenn sich die ersten oder endgültigen Grenzwerte in getrennten Zeilen befinden, gibt es zusätzliche Neulinen, während der Trennzeichen die Zeichenfolge schwieriger zu lesen macht, insbesondere für die erste Zeile, die häufig unterschiedlich als den Rest eingerichtet ist. Darüber hinaus muss das wörtliche Unbekämpfung, da die führende Weißespace erhalten bleibt - dies bricht den Fluss des Codes, wenn das wörtliche Wörtel innerhalb des eingerichteten Code auftritt.

Die häufigste Lösung für diese Probleme ist Hier Dokument-Stil String -Literale. Formell gesehen, a Hier Dokument ist keine String -Literal, sondern ein Stream -Literal oder ein Leiterleiter. Diese stammen aus Shell -Skripten und ermöglichen es, dass ein wörtlicher Literal als Eingabe in einen externen Befehl gefüttert wird. Der Eröffnungsgrenzwert ist < wo ENDE kann jedes Wort sein und der schließende Trennzeichen ist ENDE auf einer Zeile selbst und dient als Inhaltsgrenze - die << ist an der Umleitung zurückzuführen Stdin vom wörtlichen. Da der Trennzeichen willkürlich ist, vermeiden diese auch das Problem der Trennzeichenkollision. Diese ermöglichen auch die anfänglichen Registerkarten über die Variante -Syntax <<-END Obwohl die Führungsräume nicht abgezogen werden. Die gleiche Syntax wurde inzwischen für Multiline -Streich -Literale in einer Reihe von Sprachen, insbesondere Perl, übernommen und wird auch als als bezeichnet Hier Dokumente, und behalten Sie die Syntax bei, obwohl sie Saiten sind und keine Umleitung betreffen. Wie bei anderen String -Literalen können diese manchmal ein anderes Verhalten angegeben haben, wie z. B. variable Interpolation.

Python, dessen übliche Streichliterale nicht buchstäbliche Neulinge zulassen, hat stattdessen eine spezielle Form von String, die für Multiline -Literale entwickelt wurde, genannt dreifach zitieren. Diese verwenden entweder einen verdreifachten Trennzeichen '' '' oder "" ". Diese Literale werden speziell für Inline -Dokumentation verwendet, bekannt als als Docstrings.

TCL ermöglicht buchstäbliche Neulinge in Saiten und verfügt über keine spezielle Syntax, die bei Multiline -Saiten unterstützt werden, obwohl es Grenzen für sich selbst platziert und über die Führung von Newlines über die Leitungen platziert werden kann. Saitenausstattung, während String -Karte kann verwendet werden, um die Eindrücke zu streifen.

String buchstäbliche Verkettung

Ein paar Sprachen bieten String buchstäbliche Verkettung, wo benachbarte Streichliterale zur Kompilierungszeit implizit mit einem einzigen Literal verbunden sind. Dies ist ein Merkmal von C,,[8][9] C ++,[10] D,[11] Rubin,[12] und Python,[13] die es von C. kopiert hat[14] Bemerkenswerterweise erfolgt diese Verkettung zur Kompilierung der Zeit während lexikalische Analyse (als Phase nach anfänglicher Tokenisierung) und steht im Gegensatz zu beiden Laufzeiten im Gegensatz String-Verkettung (im Allgemeinen mit dem + Operator)[15] und Verkettung während Konstante Faltung, was zur Kompilierungszeit auftritt, aber in einer späteren Phase (nach Phrasenanalyse oder "Parsen"). Die meisten Sprachen wie C#, Java[16] und Perl, unterstützen Sie die implizite String buchstäbliche Verkettung nicht und erfordern stattdessen eine explizite Verkettung, wie z. B. mit dem + Operator (dies ist auch in D und Python möglich, aber illegal in C/C ++ - siehe unten); In diesem Fall kann eine Verkettung zur Kompilierung durch konstante Falten oder zur Laufzeit aufgeschoben werden.

Motivation

In C, wo das Konzept und der Begriff stammen, wurde aus zwei Gründen eine String -Literalverkleinerung eingeführt:[17]

  • Damit lange Saiten mehrere Linien mit einer ordnungsgemäßen Eindrückung im Gegensatz zur Liniendauer abspannen können, was das Einklingungsschema zerstört; und
  • Um die Konstruktion von Streichliteralen durch Makros (via "zu ermöglichen String).[18]

In praktischer Hinsicht ermöglicht dies eine String -Verkettung in frühen Zusammenstellungsphasen ("Translation", insbesondere als Teil der lexikalischen Analyse), ohne eine Phrasenanalyse oder konstante Faltung zu erfordern. Beispielsweise sind die folgenden gültigen C/C ++:

verkohlen *s = "hallo, " "Welt"; printf("hallo, " "Welt"); 

Das Folgende ist jedoch ungültig:

verkohlen *s = "hallo, " + "Welt"; printf("hallo, " + "Welt"); 

Dies liegt daran, dass String -Literale haben Array -Typ, Char [n] (C) oder const char [n] (C ++), was nicht hinzugefügt werden kann; Dies ist in den meisten anderen Sprachen keine Einschränkung.

Dies ist besonders wichtig, wenn es in Kombination mit dem verwendet wird C Präprozessor, um Strings nach Vorverarbeitung, insbesondere in Makros, zu berechnen.[14] Als einfaches Beispiel:

verkohlen *Datei_and_Message = __DATEI__ ": Botschaft"; 

Will (wenn die Datei als A.C bezeichnet wird) erweitert auf:

verkohlen *Datei_and_Message = "a.c" ": Botschaft"; 

das wird dann verkettet und gleichwertig mit:

verkohlen *Datei_and_Message = "A.C: Nachricht"; 

Ein gemeinsamer Anwendungsfall ist der Bau von Printf oder Scanf Formatketten, wo Formatspezifizierer von Makros gegeben werden.[19][20]

Ein komplexeres Beispiel verwendet Stringifikation von Ganzzahlen (durch den Präprozessor), um ein Makro zu definieren, das sich auf eine Abfolge von String -Literalen ausdehnt, die dann mit dem Dateinamen und der Zeilennummer zu einem einzigen String -Literal verkettet werden:[21]

#define stringify (x) #x #define toString (x) Stringify (x) #define bei __File__ ":" Toststring (__ Line__) 

Jenseits der syntaktischen Anforderungen von C/C ++, implizite Verkettung ist eine Form von syntethischer ZuckerEs wird einfacher, String -Literale über mehrere Zeilen zu teilen, die Notwendigkeit einer Liniendauer (über Backslashes) zu vermeiden, und ermöglicht es, Teilen von Strings Kommentare hinzuzufügen. Zum Beispiel kann man in Python a kommentieren a regulären Ausdruck auf diese Weise:[22]

betreffend.kompilieren("[A-za-z_]"  # Brief oder Unterstriche  "[A-za-z0-9 _]*"  # Brief, Ziffern oder Unterstriche  ) 

Probleme

Implizite String-Verkettung wird von modernen Compilern, die eine konstante Faltung implementieren, nicht benötigt und verursacht schwer zu findene Fehler aufgrund einer unbeabsichtigten Verkettung, indem sie ein Komma weglassen, insbesondere in vertikalen Listen von Zeichenfolgen, wie in:

l = ["Foo",  'Bar'  "Zork"] 

Dementsprechend wird es in den meisten Sprachen nicht verwendet, und es wurde zur Abschaltung von D vorgeschlagen[23] und Python.[14] Das Entfernen der Merkmals bricht jedoch nach hinten die Kompatibilität und ersetzt sie durch eine Verkettungsoperatorin vor, die vor der Operatorbewertung vorrangig Probleme mit Vorrang vorliegt. ist ein Problem, das möglicherweise Klammern verlangt, um die gewünschte Bewertungsreihenfolge sicherzustellen.

Ein subtileres Problem ist, dass in C und C ++,[24] Es gibt verschiedene Arten von String-Literalen, und die Verkettung dieser hat implementierungsdefiniertes Verhalten, das ein potenzielles Sicherheitsrisiko darstellt.[25]

Verschiedene Arten von Saiten

Einige Sprachen liefern mehr als eine Art von wörtlicher Art, die ein anderes Verhalten haben. Dies wird besonders verwendet, um anzuzeigen rohe Saiten (Keine Flucht) oder variable Interpolation zu deaktivieren oder zu aktivieren, hat jedoch andere Verwendungen, wie z. B. Unterscheidung von Zeichensätzen. Meistens wird dies durchgeführt, indem das Zitatcharakter geändert oder ein Präfix oder ein Suffix hinzugefügt wird. Dies ist vergleichbar mit Präfixen und Suffixe zu ganzzahlige Literale, wie z. B. hexadezimale Zahlen oder lange ganze Zahlen anzeigen.

Eines der ältesten Beispiele ist in Shell -Skripten, in denen einzelne Zitate eine rohe Zeichenfolge oder eine "wörtliche Zeichenfolge" angeben, während doppelte Zitate Fluchtsequenzen und variable Interpolation aufweisen.

Zum Beispiel in Python, rohe Saiten gehen von einem voraus r oder R - vergleichen 'C: \\ Windows' mit R'c: \ Windows ' (Eine Python -Rohschnur kann jedoch nicht in einer ungeraden Anzahl von Backslashes enden). Python 2 unterscheidet auch zwei Arten von Zeichenfolgen: 8-Bit-ASCII ("Bytes") Strings (der Standard), ausdrücklich mit einem angegeben b oder B Präfix und Unicode -Saiten, angezeigt mit a u oder U Präfix.[26] Während in Python 3 Saiten standardmäßig Unicode und Bytes separat sind Bytes Geben Sie das ein, wenn initialisiert mit Zitaten mit a vorangestellt werden muss b.

C#Die Notation für rohe Strings heißt @-quoting.

@"C: \ foo \ bar \ baz \" 

Während dieses Entkommens entkommen Sie, ermöglicht es Doppelzitate, mit denen sich Zitate innerhalb der Zeichenfolge darstellen:

@"Ich sagte," Hallo. " 

C ++ 11 erlaubt Rohstaaten, Unicode-Saiten (UTF-8, UTF-16 und UTF-32) und breite Zeichenketten, bestimmt durch Präfixe. Es fügt auch Literale für das vorhandene C ++ hinzu Saite, was im Allgemeinen den bestehenden C-Saiten im C-Stil bevorzugt wird.

In TCL sind die Streben mit Striche buchstäblich, während zitierte Saiten entkommen und interpoliert werden.

Perl hat eine Vielzahl von Saiten, die formeller als Betreiber betrachtet werden und als bekannt als als Zitat- und zitatartige Operatoren. Dazu gehören sowohl eine übliche Syntax (feste Abgrenzer) als auch eine generische Syntax, die eine Auswahl der Abgrenzer ermöglicht. diese beinhalten:[27]

'' '  "" "  ``  //  m//  QR //  s///  y/// q{}  qq {}  qx {}  QW {}  m{}  qr {}  s{}{}  tr{} {}  y{} {} 

Rexx Verwendet Suffix -Zeichen, um Zeichen oder Zeichenfolgen mit ihrem hexadezimalen oder binären Code anzugeben. Z.B.,

"20"x "0010 0000"b "00100000"b 

Alle ergeben die WeltraumcharakterVermeiden Sie den Funktionsaufruf X2c (20).

String -Interpolation

In einigen Sprachen können String -Literale Platzhalter enthalten, die sich auf Variablen oder Ausdrücke im Strom beziehen Kontext, die bewertet werden (normalerweise zur Laufzeit). Dies wird als bezeichnet als Variable Interpolationoder allgemeiner String -Interpolation. Sprachen, die die Interpolation unterstützen, unterscheiden im Allgemeinen Strings -Literale, die von denen interpoliert sind, die nicht sind. Zum Beispiel in sh-kompatible Unix-Schalen (sowie Perl und Ruby), doppelt zitierte (zitatverzögerte ") Saiten werden interpoliert, während einzeln zitierte (Apostroph-Delimited ') Strings nicht. Nicht-interpolierte String-Literale werden manchmal als" rohe Raw bezeichnet " Saiten ", aber dies unterscheidet sich von" rohen String "im Sinne des Flucht r oder R hat keine Flucht oder Interpolation, eine normale Zeichenfolge (kein Präfix) entkommt, aber keine Interpolation, und eine Zeichenfolge, die vorangestellt ist f oder F hat entkommen und interpolation.

Zum Beispiel die folgenden Perl Code:

$ name  = "Nancy"; $ Gruß = "Hallo Welt"; drucken "$ name sagte $ gruß an die Menge der Menschen."; 

erzeugt die Ausgabe:

Nancy sagte Hello World zu der Menge von Menschen.

In diesem Fall die Metacharakter Charakter ($) (nicht zu verwechseln mit dem Sigil in der Variablenzuweisungsanweisung) wird interpretiert, um eine variable Interpolation anzuzeigen, und erfordert einige Flüchtlinge, wenn sie buchstäblich ausgegeben werden müssen.

Dies sollte mit dem kontrastiert werden printf Funktion, die die gleiche Ausgabe unter Verwendung von Notationen erzeugt wie:

printf " %s sagte %s für die Menge von Menschen.", $ name, $ Gruß; 

führt aber keine Interpolation durch: die %s ist ein Platzhalter in a Printf -Formatzeichenfolge, aber die Variablen selbst liegen außerhalb der Saite.

Dies steht im Gegensatz zu "rohen" Saiten:

drucken "$ name sagte $ greeting an die Menge von Menschen."; 

die Ausgabe erzeugen wie:

$ name sagte $ gruß an die Menge der Menschen.

Hier sind die $ Charaktere keine Metacharacter und werden nicht als eine andere Bedeutung als einen einfachen Text interpretiert.

Einbetten von Quellcode in String -Literale einbetten

Sprachen, denen Flexibilität bei der Angabe von String -Literalen mangelt, machen es besonders umständlich, den Programmiercode zu schreiben, der andere Programmiercode generiert. Dies gilt insbesondere dann, wenn die Erzeugungssprache gleich oder ähnlich der Ausgabesprache ist.

Zum Beispiel:

  • Schreibcode zum Erstellen Quinien
  • Erzeugen einer Ausgabessprache von innerhalb von a Webvorlage;
  • Verwendung Xslt XSLT zu generieren, oder Sql mehr SQL generieren
  • Erzeugen a PostScript Darstellung eines Dokuments für Druckzwecke aus einer Dokumentverarbeitungsanwendung in geschriebener Dokumentverarbeitungsanwendung C oder eine andere Sprache.
  • Schreiben Shader

Dennoch sind einige Sprachen besonders gut angepasst, um diese Art von selbstähnlicher Ausgabe zu erzeugen, insbesondere solche, die mehrere Optionen unterstützen, um die Kollision von Graben zu vermeiden.

Die Verwendung von String -Literalen als Code, der einen anderen Code generiert, kann negative Sicherheitsauswirkungen haben, insbesondere wenn die Ausgabe zumindest teilweise auf nicht vertrauenswürdigen Benutzereingaben basiert. Dies ist besonders akut bei webbasierten Anwendungen, bei denen böswillige Benutzer solche Schwächen nutzen können, um den Betrieb der Anwendung zu untergraben, beispielsweise durch die Montage einer SQL-Injektion Attacke.

Siehe auch

Anmerkungen

  1. ^ Die hier angegebene Regex wird nicht selbst zitiert oder entkommen, um die Verwirrung zu verringern.

Verweise

  1. ^ "Einführung in Java - MFC 158 g". String -Literale (oder Konstanten) werden als "anonyme Zeichenfolgen" bezeichnet.
  2. ^ "Ansi C Grammar (Lex)". liu.se. Abgerufen 22. Juni 2016.
  3. ^ a b "Anhang B. Charaktere, Zeichenfolgen und entkommende Regeln". RealWorldhaskell.org. Abgerufen 22. Juni 2016.
  4. ^ a b "String". Mozilla.org. Abgerufen 22. Juni 2016.
  5. ^ a b c d e f g h i j k l m "Escape -Sequenzen (c)". microsoft.com. Abgerufen 22. Juni 2016.
  6. ^ a b "Begründung für internationalen Standard - Programmiersprachen - C" (PDF). 5.10. April 2003. S. 52, 153–154, 159. Archiviert (PDF) vom Original am 2016-06-06. Abgerufen 2010-10-17.
  7. ^ "6.35 Das Charakter <Ct> in Konstanten", GCC 4.8.2 Handbuch, abgerufen 2014-03-08
  8. ^ C11 Entwurfsstandard, WG14 N1570 Ausschussentwurf - 12. April 2011, 5.1.1.2 Übersetzungsphasen, p. 11: "6. benachbarte Streichstraße sind verkettet."
  9. ^ C Syntax: String Literaler Verkettung
  10. ^ C ++ 11 Entwurfsstandard, "Arbeitsentwurf, Standard für die Programmiersprache C ++" (PDF)., 2.2 Übersetzungsphasen [Lex.Phasen], p. 17: "6. benachbarte Streichstraße sind verkettet." und 2.14.5 String -Literale [Lex.String], Anmerkung 13, p. 28–29: "In der Übersetzungsphase 6 (2.2) sind benachbarte String -Literale verkettet."
  11. ^ D Programmiersprache, Lexikalische Analyse, "String -Literale": "benachbarte Saiten werden mit dem ~ Operator oder durch einfache Gegenüberstellung verkettet:"
  12. ^ Ruby: Die Ruby -Programmiersprache, Ruby-Programmiersprache, 2017-10-19, abgerufen 2017-10-19
  13. ^ Die Python -Sprachreferenz, 2. lexikalische Analyse, 2.4.2. String buchstäbliche Verkettung: "Mehrere benachbarte String -Literale (durch Whitespace abgenommen), möglicherweise mit unterschiedlichen Zitatkonventionen, sind erlaubt, und ihre Bedeutung ist mit ihrer Verkettung die gleiche."
  14. ^ a b c Python-ideas, "Implizite String -Literalverkampferung als schädlich angesehen?", Guido van Rossum, 10. Mai 2013
  15. ^ Die Python -Sprachreferenz, 2. lexikalische Analyse, 2.4.2. String buchstäbliche Verkettung: "Beachten Sie, dass diese Funktion auf syntaktischer Ebene definiert ist, jedoch zum Kompilierungszeit implementiert wird. Der Betreiber"+"muss verwendet werden, um String -Ausdrücke zur Laufzeit zu verkettet."
  16. ^ "Saiten (die Java ™ -Tutorials> Lernen der Java -Sprache> Zahlen und Strings)". Docs.oracle.com. 2012-02-28. Abgerufen 2016-06-22.
  17. ^ Begründung für die ANSI C -Programmiersprache. Silicon Press. 1990. p.31. ISBN 0-929306-07-4., 3.1.4 String -Literale: "Eine lange Zeichenfolge kann über mehrere Zeilen fortgesetzt werden, indem die Fortsetzung der Backslash-Newline-Linie verwendet wird. Diese Praxis erfordert jedoch, dass die Fortsetzung der String in der ersten Position der nächsten Zeile beginnt. Um flexibleres Layout zu ermöglichen und einige zu lösen Vorverarbeitungsprobleme (siehe §3.8.3) stellte das Komitee eine String -Literalverkleinerung vor. Zwei String -Literale in einer Reihe werden zusammen eingefügt (ohne Nullcharakter in der Mitte), um eine kombinierte Streicher -Literal zu erzeugen. Diese Ergänzung zur C -Sprache ermöglicht a a Programmierer, um ein String buchstäblich über das Ende einer physischen Linie hinaus zu erweitern, ohne den Mechanismus des Backslash-Newline verwenden zu -Time Operation. "
  18. ^ Begründung für die ANSI C -Programmiersprache. Silicon Press. 1990. p.6566. ISBN 0-929306-07-4., 3.8.3.2 Der # Operator: "Der # Operator wurde für das Stringrizieren eingeführt. Es kann nur in einer # Define -Expansion verwendet werden. Es führt dazu Verkettung (siehe §3.1.4) ermöglicht die Verwendung dieses Bedieners die Konstruktion von Zeichenfolgen genauso effektiv wie durch den Austausch von Kennung innerhalb einer Zeichenfolge. Ein Beispiel im Standard zeigt diese Funktion. "
  19. ^ C/C ++ Users Journal, Band 19, p. 50
  20. ^ "Python - Warum eine Verkettung von Streichliteralen zulassen?". Paketüberfluss. Abgerufen 2016-06-22.
  21. ^ "Zeile __ zu String (Stringyify) Verwenden von Präzessor -Direktiven". Decompile.com. 2006-10-12. Abgerufen 2016-06-22.
  22. ^ Die Python -Sprachreferenz, 2. lexikalische Analyse, 2.4.2. String buchstäbliche Verkettung: "Diese Funktion kann verwendet werden, um die Anzahl der benötigten Rückstände zu verringern, lange Saiten bequem über lange Zeilen zu teilen oder sogar Kommentare zu Teilen von Zeichenfolgen hinzuzufügen, zum Beispiel:
  23. ^ Dlangs Ausgabe -Tracking -System - Ausgabe 3827 - Warnen Sie vor und dann implizite Verkettung benachbarter Streichliterale
  24. ^ C ++ 11 Entwurfsstandard, "Arbeitsentwurf, Standard für die Programmiersprache C ++" (PDF)., 2.14.5 String -Literale [Lex.String], Anmerkung 13, p. 28–29: "Alle anderen Verkettungen werden mit der implementierungsdefinierten Verhalten bedingt unterstützt."
  25. ^ "Archivierte Kopie". Archiviert von das Original am 14. Juli 2014. Abgerufen 3. Juli, 2014.{{}}: CS1 Wartung: Archiviertes Kopie als Titel (Link)
  26. ^ "2. Lexikalanalyse - Python 2.7.12RC1 -Dokumentation". python.org. Abgerufen 22. Juni 2016.
  27. ^ "Perlop - perldoc.perl.org". Perl.org. Abgerufen 22. Juni 2016.

Externe Links