Une chaîne littérale , ou chaîne anonyme, est une représentation littérale d'une valeur de type chaîne de caractères dans le code source . Généralement, un langage de programmation inclut une construction de code représentant une chaîne littérale : une suite de caractères délimitée par des crochets est lui-même encodé sous forme de chaîne littérale, foomais il existe de nombreuses autres variantes.
`) et/ou les guillemets simples (par exemple, `"" Python, la chaîne `""` est valide car les guillemets extérieurs sont des guillemets doubles, ce qui rend les guillemets simples intérieurs interprétables comme du texte normal.Une chaîne vide s'écrit ou PostScript utilise des parenthèses, comme dans (The quick (brown fox))` <m4> `, un accent grave au début et une apostrophe à la fin. Tcl autorise à la fois les guillemets et les accolades, comme dans ` <m4> ` ou ` <m4> `. Ceci provient des guillemets simples des shells Unix et de l’utilisation des accolades en C pour les instructions composées, car les blocs de code sont syntaxiquement identiques aux chaînes littérales en Tcl ; l’appariement des délimiteurs est donc essentiel."The quick brown fox"{The quick {brown fox}}
Les citations sont généralement écrites avec des guillemets simples, mais certains outils et jeux de caractères prennent en charge les guillemets doubles. Les guillemets simples sont des guillemets qui ne possèdent pas de variantes distinctes pour les guillemets gauche et droit, comme `\` ""ou `\` ''. Le jeu de caractères Unicode inclut des versions avec guillemets doubles :
"Salut!" 'Salut!' "Salut!" "Salut!"
Mélange de portée
Le mélange de portées consiste à mélanger les portées au lieu de les organiser de manière purement hiérarchique .
En d'autres termes, le « mélange de portée » se produit lorsqu'il n'existe pas de délimiteur de début (ou de fin) non ambigu .
Voici des exemples de citations sortant de leur propre contexte (qui sont des chaînes de caractères illégales) :
"InsideTheOuterString 'InnerString_ButWithUnmatchedEndingSingleQuoteThatRendersThisStringInvalid" ErroneousStringThatIsSomehowInsideTheInnerStringYetNotInsideTheOuterString'"1 '2" 3'"Inside1 'InsideBoth1and2" Inside2'
Les chaînes de caractères littérales ne permettent pas le mélange de portées, car cela crée des programmes ambigus. Une chaîne de caractères littérale peut parfois sembler avoir des portées mixtes, mais il existe des règles de priorité des opérateurs propres à chaque langage de programmation pour éviter toute ambiguïté, comme la méthode consistant à lire les expressions du caractère le plus à gauche vers le caractère le plus à droite, en donnant à un "symbole situé à gauche une priorité plus élevée que tout autre guillemet qui le suit (sur la même ligne).
Comme mentionné précédemment, les guillemets imbriqués peuvent être valides, comme dans , mais ils nécessitent une méthode qui utilise une hiérarchie (généralement une structure de données de pile ), que cette hiérarchie utilise des caractères de délimitation uniques , des caractères d'échappement ou des délimiteurs de caractères répétés .
Le « mélange de portée » est un cas particulier de collision de délimiteurs, expliqué plus loin sur cette page.
délimité par des espaces blancs
Un langage peut prendre en charge les chaînes multilignes. En YAML , les littéraux de chaînes peuvent être spécifiés par le positionnement relatif des espaces et de l'indentation.
reda`, green`b` et ` bluec` sont des chaînes de caractères littérales, même si elles ne sont pas entre guillemets :%map = ( rouge => 0x00f , bleu => 0x0f0 , vert => 0xf00 );
Perl considère une séquence de caractères alphanumériques non réservée comme une chaîne littérale dans la plupart des contextes. Par exemple, les deux lignes de code Perl suivantes sont équivalentes :
Notation déclarative
La longueur d'une chaîne littérale peut être encodée au début du texte, ce qui évite d'avoir à marquer le début et la fin de la chaîne. Par exemple, en FORTRAN , les chaînes littérales étaient écrites en notation Hollerith : le nombre décimal de caractères était suivi de la lettre H, puis des caractères de la chaîne.
Collision de délimiteur
car le second guillemet est interprété comme la fin de la chaîne et non comme sa valeur. De même, on ne peut pas écrire ` `, "This is "in quotes", but invalid."car la partie centrale entre guillemets est interprétée comme étant en dehors des guillemets. Il existe diverses solutions, la plus générale étant l'utilisation de séquences d'échappement, telles que `\ "\""n` ou `\ "This is \"in quotes\" and properly escaped."r`, mais il en existe bien d'autres.Les guillemets appariés, tels que les accolades en Tcl, permettent des chaînes imbriquées, comme {foo {bar} zork}mais ne résolvent pas autrement le problème de la collision de délimiteurs, car un délimiteur de fermeture déséquilibré ne peut pas simplement être inclus, comme dans {}}.
Doubler
Plusieurs langages, dont Pascal , BASIC , DCL , Smalltalk , SQL , J et Fortran , évitent les conflits de délimiteurs en doublant les guillemets qui sont censés faire partie de la chaîne littérale elle-même :
R" end-of-string-id ( content ) end-of-string-id ",
Autrement dit, après R"avoir saisi jusqu'à 16 caractères (espaces, parenthèses et barre oblique inverse exclus) formant l' identifiant de fin de chaîne (répété pour signaler la fin de la chaîne ), le programmeur doit ensuite ajouter une parenthèse ouvrante (indiquant la fin de l' identifiant de fin de chaîne). Vient ensuite le contenu de la chaîne littérale : toute séquence de caractères est autorisée (sauf une parenthèse fermante suivie de l'identifiant de fin de chaîne et d'un guillemet). Enfin, pour terminer la chaîne, une parenthèse fermante, l'identifiant de fin de chaîne et un guillemet sont requis. Le cas le plus simple est celui d'une chaîne littérale vide, sans identifiant de fin de chaîne : `<?xml="16" />`. L'identifiant de fin de chaîne peut contenir des guillemets : `<?xml="16" / R"()"> ` est une chaîne littérale valide (l'identifiant de fin de chaîne est ici). Les séquences d'échappement ne fonctionnent pas avec les chaînes littérales brutes."(I asked, "Can you hear me?")"""
D prend en charge quelques délimiteurs de guillemets, ces chaînes commençant par q"un délimiteur ouvrant et se terminant par le délimiteur fermant correspondant ". Les paires de délimiteurs disponibles sont ()`\`, `\` <>, {}`\` et ` []\`. Un délimiteur non apparié et non identifiant est son propre délimiteur fermant. Les paires de délimiteurs s'imbriquent, de sorte que `\` est une chaîne littérale valide ; un exemple avec le caractère non imbriqué est `\ `. Comme en C++11, D autorise les littéraux de type « here-document » avec des identifiants de fin de chaîne./
q" end-of-string-id newline content newline end-of-string-id "
En D, l' identifiant de fin de chaîne doit être un identifiant (caractères alphanumériques).
Dans certains langages de programmation, tels que sh et Perl , il existe différents délimiteurs qui sont traités différemment, par exemple en effectuant ou non une interpolation de chaînes, et il faut donc faire attention au choix du délimiteur à utiliser ; voir la section sur les différents types de chaînes ci-dessous.
devis multiples
Une autre extension consiste à utiliser les guillemets multiples , ce qui permet à l'auteur de choisir les caractères qui doivent spécifier les limites d'une chaîne littérale.
Par exemple, en Perl :
Lua (à partir de la version 5.1) offre une forme limitée de guillemets multiples, notamment pour permettre l'imbrication de longs commentaires ou de chaînes de caractères. On utilise généralement `\` [[et ]]`\` pour délimiter les chaînes littérales (le saut de ligne initial est supprimé, sinon la chaîne est brute), mais les crochets ouvrants peuvent contenir un nombre quelconque de signes égal, et seuls les crochets fermants contenant le même nombre de signes permettent de fermer la chaîne. Par exemple :
s/regex/replacement//s,regex,replacement,Fonctions constructeurs
Une autre option, rarement employée dans les langages modernes, consiste à utiliser une fonction pour construire une chaîne de caractères, plutôt que de la représenter par une valeur littérale. Cette méthode est généralement évitée car le calcul est effectué à l'exécution et non à l'analyse syntaxique.
Par exemple, les premières versions de BASIC n'incluaient pas les séquences d'échappement ni aucune autre solution de contournement mentionnée ici ; il fallait donc utiliser la CHR$fonction qui renvoie une chaîne contenant le caractère correspondant à son argument. En ASCII, le guillemet a la valeur 34 ; ainsi, pour représenter une chaîne avec des guillemets sur un système ASCII, on écrirait :
En C, une fonctionnalité similaire est disponible via sprintfle %cspécificateur de format « character », bien que, en présence d’autres solutions de contournement, elle ne soit généralement pas utilisée :
Ces fonctions constructeurs peuvent également servir à représenter des caractères non imprimables, bien que l'on utilise généralement des séquences d'échappement. Une technique similaire peut être employée en C++ avec l' std::stringopérateur de conversion en chaîne de caractères.
séquences d'évasion
\\et que, pour les chaînes délimitées, le délimiteur peut être encodé en l'échappant, par exemple par `\` \"pour `"`. Une expression régulière pour de telles chaînes échappées peut être donnée comme suit, telle qu'elle figure dans la spécification ANSI C : "Cela signifie « une apostrophe ; suivie de zéro ou plusieurs caractères d’échappement (une barre oblique inverse suivie d’un autre caractère, éventuellement une barre oblique inverse ou une apostrophe), ou d’un caractère non échappé et non apostrophe ; se terminant par une apostrophe ». La seule difficulté réside dans la distinction entre l’apostrophe finale et une apostrophe précédée d’une barre oblique inverse, laquelle peut elle-même être échappée. Plusieurs caractères peuvent suivre la barre oblique inverse, comme « \ » \uFFFF, selon le système d’échappement.
Une chaîne de caractères échappée doit ensuite être analysée lexicalement afin de la convertir en la chaîne non échappée qu'elle représente. Cette opération a lieu lors de la phase d'évaluation de l'analyse lexicale globale du langage : l'évaluateur de l'analyseur lexical du langage global exécute son propre analyseur lexical pour les littéraux de chaînes échappées.
Il doit notamment être possible d'encoder le caractère qui termine normalement une chaîne de caractères, et il doit exister un moyen de spécifier le caractère d'échappement lui-même. Les séquences d'échappement ne sont pas toujours élégantes ni faciles à utiliser ; c'est pourquoi de nombreux compilateurs proposent d'autres solutions aux problèmes courants. Les séquences d'échappement, en revanche, résolvent tous les problèmes de délimitation et la plupart des compilateurs les interprètent. Lorsqu'un caractère d'échappement se trouve dans une chaîne de caractères, il signifie « ceci est le début de la séquence d'échappement ». Chaque séquence d'échappement spécifie un caractère à insérer directement dans la chaîne. Le nombre de caractères requis dans une séquence d'échappement varie. Le caractère d'échappement se trouve en haut à gauche du clavier, mais l'éditeur le traduit ; il n'est donc pas directement saisi dans une chaîne. La barre oblique inverse (\) est utilisée pour représenter le caractère d'échappement dans une chaîne de caractères.
De nombreux langages permettent l'utilisation de métacaractères dans les chaînes de caractères. L'interprétation des métacaractères varie selon le contexte et le langage, mais il s'agit généralement d'une sorte de « commande de traitement » permettant de représenter des caractères imprimables ou non imprimables.
Par exemple, dans une chaîne de caractères littérale en C , si la barre oblique inverse est suivie d'une lettre comme « b », « n » ou « t », cela représente respectivement un retour arrière , un saut de ligne ou une tabulation . De même, si la barre oblique inverse est suivie de 1 à 3 chiffres octaux , cette séquence est interprétée comme représentant l'unité de code arbitraire ayant la valeur spécifiée dans l'encodage de la chaîne littérale (par exemple, le code ASCII correspondant à une chaîne littérale ASCII). Cette fonctionnalité a ensuite été étendue pour prendre en charge les notations de codage de caractères hexadécimales plus modernes .
| Séquence d'évasion | Unicode | Caractères littéraux placés dans une chaîne |
|---|---|---|
| \0 | U+0000 | caractère nul (généralement comme cas particulier de la notation octale \ooo) |
| caractère d'échappement ( GCC , clang et tcc ) | ||
| Caractère Unicode 16 bits où #### sont quatre chiffres hexadécimaux | ||
| U+0022 | guillemet double ("") | |
des requêtes préparées afin de prévenir les attaques par injection de code . De PHP 2 à 5.3, une fonctionnalité appelée « guillemets magiques » permettait d'échapper automatiquement les chaînes de caractères (pour plus de simplicité et de sécurité), mais elle a été supprimée à partir de la version 5.4 en raison de problèmes rencontrés.cordes brutesCertains langages offrent la possibilité de spécifier qu'une valeur littérale doit être traitée sans interprétation propre au langage. Cela évite le recours à l'échappement et produit des chaînes de caractères plus lisibles. Les chaînes de caractères brutes sont particulièrement utiles lorsqu'il est nécessaire d'échapper un caractère courant, notamment dans les expressions régulières (imbriquées sous forme de littéraux de chaîne), où la barre oblique inverse est fréquemment utilisée, et dans les chemins @"Le chemin d'accès Windows est C:\Foo\Bar\Baz\" Des cas extrêmes se produisent lorsque ces éléments sont combinés : les chemins UNC commencent par `\` Dans les documents XML, les sections CDATA permettent l'utilisation de caractères tels que & et < sans que l'analyseur XML ne tente de les interpréter comme faisant partie de la structure du document. Ceci peut s'avérer utile lors de l'inclusion de texte brut et de code de script, afin de garantir la bonne formation du document . Ce sont deux instructions BASH valides , produisant toutes deux la même sortie : nourriture bar Parmi les langages autorisant les sauts de ligne littéraux, on trouve BASH , Lua , Perl , PHP , R et Tcl . Dans certains autres langages, les chaînes de caractères littérales ne peuvent pas contenir de sauts de ligne. Deux problèmes liés aux chaînes de caractères multilignes sont les sauts de ligne en début et en fin de chaîne, ainsi que l'indentation. Si les délimiteurs de début et de fin sont sur des lignes distinctes, des sauts de ligne supplémentaires apparaissent. En revanche, s'ils ne le sont pas, le délimiteur rend la chaîne plus difficile à lire, notamment pour la première ligne, souvent indentée différemment des autres. De plus, la chaîne doit être non indentée, car les espaces en début de chaîne sont conservés ; cela perturbe le flux d'exécution du code si la chaîne apparaît dans du code indenté. La solution la plus courante à ces problèmes est l'utilisation de chaînes de caractères littérales de type « here document » . Formellement, un « here document » n'est pas une chaîne de caractères littérale, mais plutôt un flux littéral ou un fichier littéral. Issus des scripts shell, ils permettent de fournir une chaîne littérale en entrée à une commande externe. Le délimiteur d'ouverture est un mot quelconque, et le délimiteur de fermeture est placé sur une ligne distincte, servant de limite de contenu ; cette différence est due à la redirection de l'entrée standard (stdin) depuis la chaîne littérale. Le caractère arbitraire du délimiteur évite également les conflits de délimiteurs. Il est possible de supprimer les tabulations initiales grâce à la syntaxe `variant`, mais les espaces de début ne sont pas supprimés. Cette même syntaxe a depuis été adoptée pour les chaînes de caractères littérales multilignes dans plusieurs langages, notamment Perl. Ces chaînes sont également appelées « here documents » et conservent la même syntaxe, bien qu'il s'agisse de chaînes de caractères et qu'aucune redirection ne soit nécessaire. Comme pour les autres chaînes de caractères littérales, il est parfois possible de spécifier un comportement différent, tel que l'interpolation de variables. Python, dont les chaînes de caractères classiques n'autorisent pas les sauts de ligne, propose une forme spéciale de chaînes, conçue pour les chaînes multilignes, appelée triple guillemets . Celles-ci utilisent un triple délimiteur, soit `\`, soit Tcl autorise les sauts de ligne littéraux dans les chaînes et ne dispose d'aucune syntaxe spéciale pour gérer les chaînes multilignes, bien que les délimiteurs puissent être placés sur les lignes elles-mêmes et que les sauts de ligne de début et de fin puissent être supprimés via concaténation de chaînes littérales+ ) et de la concaténation lors du repliement des constantes , qui a lieu à la compilation, mais plus tard (après l'analyse syntaxique). La plupart des langages, tels que C#, Java et Perl, ne prennent pas en charge la concaténation implicite de chaînes littérales et nécessitent plutôt une concaténation explicite, comme avec l' +opérateur (ceci est également possible en D et Python, mais illégal en C/C++ – voir ci-dessous) ; dans ce cas, la concaténation peut avoir lieu au moment de la compilation, via le pliage de constantes, ou peut être différée au moment de l'exécution.MotivationEn C, où le concept et le terme prennent naissance, la concaténation de littéraux de chaînes a été introduite pour deux raisons :
Concrètement, cela permet la concaténation de chaînes de caractères dès les premières phases de compilation (« traduction », notamment dans le cadre de l’analyse lexicale), sans nécessiter d’analyse de syntagmes ni de simplification des constantes. Par exemple, le code C suivant est valide : "monde" ; printf ( "bonjour, " "monde" ); Cependant, ce qui suit est invalide : + "monde" ; printf ( "bonjour, " + "monde" ); En effet, les littéraux de chaîne de caractères sont de type tableau ( Ceci est particulièrement important lorsqu'il est utilisé en combinaison avec le préprocesseur C , afin de permettre le calcul des chaînes de caractères après le prétraitement, notamment dans les macros. À titre d'exemple simple : ; (si le fichier s'appelle ac) se développera en : ": message" ; qui est ensuite concaténé, ce qui équivaut à : ; Un cas d'utilisation courant consiste à construire Un exemple plus complexe utilise la conversion en chaîne de caractères d'entiers (par le préprocesseur) pour définir une macro qui se développe en une séquence de chaînes littérales, qui sont ensuite concaténées en une seule chaîne littérale avec le nom du fichier et le numéro de ligne : Au-delà des exigences syntaxiques du C/C++, la concaténation implicite est une forme de sucre syntaxique qui simplifie la répartition des chaînes de caractères sur plusieurs lignes, évitant ainsi le recours à la continuation de ligne (via des barres obliques inverses) et permettant d'ajouter des commentaires à des parties de chaînes. Par exemple, en Python, on peut commenter une expression régulière de cette manière : # lettre ou trait de soulignement "[A-Za-z0-9_]*" # lettre, chiffre ou trait de soulignement ) ProblèmesLa concaténation implicite de chaînes de caractères n'est pas requise par les compilateurs modernes, qui implémentent le pliage des constantes, et provoque des erreurs difficiles à repérer en raison de la concaténation involontaire due à l'omission d'une virgule, en particulier dans les listes horizontales de chaînes de caractères, comme dans : , "bar" "zork" ] Par conséquent, cette fonctionnalité n'est pas utilisée dans la plupart des langages et son abandon a été proposé dans D et Python . Cependant, sa suppression rompt la compatibilité ascendante et son remplacement par un opérateur de concaténation soulève des problèmes de priorité : la concaténation de chaînes littérales a lieu lors de l'analyse lexicale, avant l'évaluation de l'opérateur, tandis que la concaténation via un opérateur explicite a lieu simultanément avec d'autres opérateurs. La priorité pose donc problème et pourrait nécessiter l'utilisation de parenthèses pour garantir l'ordre d'évaluation souhaité. Un problème plus subtil réside dans le fait qu'en C et C++, il existe différents types de littéraux de chaînes, et que la concaténation de ceux-ci a un comportement défini par l'implémentation, ce qui pose un risque potentiel pour la sécurité. Différents types de cordesCertains langages proposent plusieurs types de littéraux, chacun ayant un comportement différent. Ceci est particulièrement utile pour indiquer des chaînes de caractères brutes (sans échappement), ou pour activer ou désactiver l'interpolation de variables, mais aussi pour distinguer d'autres jeux de caractères. Le plus souvent, cela se fait en modifiant le caractère de guillemet ou en ajoutant un préfixe ou un suffixe. C'est comparable aux préfixes et suffixes utilisés pour les littéraux entiers , par exemple pour indiquer les nombres hexadécimaux ou les entiers longs. L'un des exemples les plus anciens se trouve dans les scripts shell, où les guillemets simples indiquent une chaîne brute ou « chaîne littérale », tandis que les guillemets doubles contiennent des séquences d'échappement et permettent l'interpolation de variables. Par exemple, en Python , les chaînes brutes sont précédées d'un `\` La notation C# pour les chaînes de caractères brutes est appelée citation @. Bien que cela désactive l'échappement, cela autorise les guillemets doubles, ce qui permet de représenter des guillemets à l'intérieur de la chaîne : C++11 autorise les chaînes de caractères brutes, les chaînes Unicode (UTF-8, UTF-16 et UTF-32) et les chaînes de caractères larges, identifiées par des préfixes. Il introduit également les littéraux pour les chaînes de caractères existantes en C++ En Tcl, les chaînes de caractères délimitées par des accolades sont littérales, tandis que les chaînes de caractères délimitées par des guillemets comportent des caractères d'échappement et d'interpolation. Perl possède une grande variété de chaînes de caractères, considérées plus formellement comme des opérateurs, et connues sous le nom d'opérateurs de citation et d'opérateurs de type citation . Celles-ci comprennent à la fois une syntaxe usuelle (délimiteurs fixes) et une syntaxe générique, qui permet de choisir les délimiteurs. Elles incluent : REXX utilise des caractères de suffixe pour spécifier des caractères ou des chaînes de caractères à l'aide de leur code hexadécimal ou binaire. Par exemple : b "00100000" b tous produisent le caractère espace , évitant ainsi l'appel de fonction interpolation de chaînesrou ` Rf` est appelée chaîne brute et ne comporte ni échappement ni interpolation une chaîne normale (sans préfixe) comporte un échappement mais pas d'interpolation et une chaîne préfixée par `f` fou `f` Fest appelée chaîne f et comporte un échappement et une interpolation Par exemple, le code Perl suivant : ; $greeting = "Bonjour le monde" ; print "$name a dit $greeting à la foule." ; produit le résultat suivant : Nancy a salué la foule d'un « Bonjour le monde ! ». Dans ce cas, le caractère métacaractère ($) (à ne pas confondre avec le sigil dans l'instruction d'affectation de variable) est interprété comme indiquant une interpolation de variable et nécessite une échappement s'il doit être affiché littéralement. Il convient de contraster cela avec la , $name , $greeting ; mais n'effectue pas d'interpolation : il Cela contraste avec les chaînes de caractères « brutes » : des quines Néanmoins, certaines langues sont particulièrement bien adaptées pour produire ce type de sortie auto-similaire, notamment celles qui prennent en charge plusieurs options pour éviter les collisions de délimiteurs. L'utilisation de chaînes de caractères littérales comme code générant du code peut avoir des conséquences néfastes en matière de sécurité, notamment si le résultat repose, même partiellement, sur des données utilisateur non fiables. Ce risque est particulièrement élevé pour les applications web, où des utilisateurs malveillants peuvent exploiter ces failles pour en perturber le fonctionnement, par exemple en lançant une attaque par injection SQL . |