web-dev-qa-db-fra.com

Chaînes multilignes en JSON

J'écris des fichiers de données au format JSON et j'aimerais avoir de très longues valeurs de chaîne réparties sur plusieurs lignes. En utilisant le module JSON de Python, je reçois un grand nombre d'erreurs, que j'utilise \ ou \n comme échappement. 

Est-il possible d'avoir des chaînes multilignes en JSON? C'est principalement pour le confort visuel, donc je suppose que je peux juste activer Word Wrap dans mon éditeur, mais je suis un peu curieux ...

466
Anonnobody

JSON n'autorise pas les sauts de ligne réels. Vous devez remplacer tous les sauts de ligne par \n.

par exemple: 

"first line second line"

peut être enregistré avec:

"first line\nsecond line"

Remarque:

pour Python, ceci devrait être écrit comme suit:

"first line\\nsecond line"

\\ est utilisé pour échapper à la barre oblique inversée, sinon Python traitera \n comme le caractère de contrôle "nouvelle ligne"

310
YOU

J'ai dû le faire pour un petit projet Node.js et j'ai trouvé ceci solution de contournement :

{
 "modify_head": [

  "<script type='text/javascript'>",
  "<!--",
  "  function drawSomeText(id) {",
  "  var pjs = Processing.getInstanceById(id);",
  "  var text = document.getElementById('inputtext').value;",
  "  pjs.drawText(text);}",
  "-->",
  "</script>"

 ],

 "modify_body": [

  "<input type='text' id='inputtext'></input>",
  "<button onclick=drawSomeText('ExampleCanvas')></button>"

 ],
}

Cela me semble assez chouette, à part ça, je dois utiliser des guillemets partout. Sinon, je pourrais peut-être utiliser YAML, mais cela présente d'autres pièges et n'est pas pris en charge de manière native. Une fois analysé, j'utilise simplement myData.modify_head.join('\n') ou myData.modify_head.join(), selon que je souhaite ou non un saut de ligne après chaque chaîne.

171
errordeveloper

Découvrez les spécifications ! La production char de la grammaire JSON peut prendre les valeurs suivantes:

  • tout-caractère-Unicode-sauf -"- ou -\- ou caractère de contrôle
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \uquatre-hex-digits

Les nouvelles lignes sont des "caractères de contrôle", alors non, vous ne pouvez pas avoir de nouvelle ligne littérale dans votre chaîne. Cependant, vous pouvez l'encoder en utilisant la combinaison de \n et \r dont vous avez besoin.

C'est une question très ancienne, mais je l'ai trouvée lors d'une recherche et je pense connaître la source de votre problème.

JSON n'autorise pas les "vraies" nouvelles lignes dans ses données; il ne peut avoir échappé aux newlines. Voir le répondre de @YOU . Selon la question, il semblerait que vous ayez tenté d'échapper aux sauts de ligne en Python de deux manières: en utilisant le caractère de continuation de ligne ("\") ou en utilisant "\n" comme échappement.

Mais gardez à l'esprit que si vous utilisez une chaîne en python, les caractères d'échappement spéciaux ("\t", "\n") sont traduits en caractères de contrôle REAL! Le "\n" sera remplacé par le caractère de contrôle ASCII représentant un caractère de nouvelle ligne, qui est précisément le caractère illégal en JSON. (Quant au caractère de continuation de ligne, il supprime simplement la nouvelle ligne.)

Donc, ce que vous devez faire est d'empêcher Python d'échapper aux caractères. Vous pouvez le faire en utilisant une chaîne brute (mettez r devant la chaîne, comme dans r"abc\ndef", ou en insérant une barre oblique supplémentaire devant la nouvelle ligne ("abc\\ndef").

Au lieu de remplacer "\n" par le caractère réel de contrôle de nouvelle ligne ASCII, les deux opérations ci-dessus laisseront "\n" sous la forme de deux caractères littéraux, que JSON pourra alors interpréter comme un échappement de nouvelle ligne.

34
HardlyKnowEm

JSON n'autorise pas les lignes de rupture pour la lisibilité.

Votre meilleur choix est d’utiliser un IDE qui vous mettra à la ligne.

31
James Gentes

Malheureusement, beaucoup de réponses ici abordent la question de savoir comment insérer un caractère de nouvelle ligne dans les données de chaîne. La question est de savoir comment rendre le code plus agréable en fractionnant la valeur de chaîne sur plusieurs lignes de code. (Et même les réponses qui reconnaissent ceci fournissent des "solutions" qui supposent que l’on est libre de changer la représentation des données, ce qui n’est souvent pas le cas.)

Et la pire nouvelle est qu’il n’ya pas de bonne réponse.

Dans de nombreux langages de programmation, même s'ils ne prennent pas explicitement en charge le fractionnement de chaînes sur plusieurs lignes, vous pouvez toujours utiliser la concaténation de chaînes pour obtenir l'effet souhaité. et tant que le compilateur n'est pas terrible, tout va bien.

Mais json n’est pas un langage de programmation; c'est juste une représentation de données. Vous ne pouvez pas lui dire de concaténer des chaînes. Sa grammaire (assez petite) n'inclut pas non plus de possibilité de représenter une chaîne sur plusieurs lignes.

À moins de concevoir un pré-processeur quelconque (et je n'ai pas l'impression de composer efficacement mon propre langage pour résoudre ce problème), il n'existe pas de solution générale à ce problème. SI vous pouvez changer le format de données, vous pouvez alors substituer un tableau de chaînes. Sinon, c’est l’un des nombreux moyens par lesquels JSON n’est pas conçu pour la lisibilité.

18
Mark Adelsberger

Ecrivez la valeur de la propriété sous forme de tableau de chaînes. Comme exemple donné ici https://gun.io/blog/multi-line-strings-in-json/ . CA aidera.

Nous pouvons toujours utiliser un tableau de chaînes pour les chaînes multilignes, comme suit.

{
    "singleLine": "Some singleline String",
    "multiline": ["Line one", "line Two", "Line Three"]
} 

Et nous pouvons facilement parcourir un tableau pour afficher le contenu de manière multiligne.

11
Sandip Nirmal

Est-il possible d'avoir des chaînes multi-lignes en JSON?

Oui. Je viens de tester cela maintenant avec mon navigateur Web Firefox en appuyant sur F12, en cliquant sur console et en tapant au bas de l'écran.

x={text:"hello\nworld"}

L'objet x vient d'être créé à partir d'une chaîne de format JSON contenant une chaîne multiligne.

console.log(x.text)
hello
world

x.text s'affiche, indiquant qu'il s'agit d'une chaîne multiligne.

Ces deux tests montrent que l'interpréteur Javascript de Firefox est heureux de créer et d'utiliser JSON avec des chaînes multilignes.

D'autres tests avec JSON.stringify et JSON.parse ont montré que l'interpréteur Javascript peut convertir un objet contenant des chaînes multilignes en JSON et le réanalyser sans problème.

Dans le passé, j'ai stocké les œuvres complètes de Shakespeare en tant que propriété dans un objet JSON, puis je les ai envoyées par Internet, sans aucune corruption.

Exemple

Voici une chaîne de deux lignes entrée sur trois lignes

x={text:"expert\
s\nex\
change"}

Nous pouvons afficher l'objet

console.log(x)

donnant 

Object { text: "experts\nexchange" }

ou la ficelle

console.log(x.text)

donnant 

experts
exchange

La fin des lignes de la chaîne résulte de l’utilisation de\n .__ et les multiples lignes d’entrée sont obtenues en utilisant simplement\à la fin de la ligne.

En pratique, vous voudrez peut-être synchroniser vos fins de ligne avec celles de la chaîne, par exemple.

x={text:"experts\n\
exchange"}

Longueur de chaîne multiligne

console.log("Hello\nWorld".length)
11 
console.log("Hello World".length)
11

Notez que la chaîne avec la nouvelle ligne n'est pas plus longue que la chaîne avec l'espace. Même si deux caractères ont été tapés sur le clavier ('\' et 'n'), un seul caractère est stocké dans la chaîne.

11
user3070485

Utilisez regex pour remplacer toutes les occurrences de \r\n par \\n.

Cela a fonctionné pour moi en scala.

val newstr = str.replace("\r\n", "\\n")
9
Sikander

Si vous voulez utiliser Node.js, vous pouvez faire ceci:

module.exports = {

  multilineStr: `

     dis my life 
     it's now or never

  `

}

vous pouvez importer avec Node.js et le convertir en JSON facilement comme ceci:

echo `node -pe 'JSON.stringify(require("./json-mod.js"))'`

et vous obtenez:

{"multilineStr":"\n \n dis my life\n it's now or never\n \n "}

comment ça marche : vous utilisez Node.js pour charger un module JS, qui crée un objet JS pouvant être facilement transformé en JSON par Node.js. L'option -e évalue la chaîne et l'option -p renvoie le résultat de la dernière opération Node.js à stdout.

Si vous voulez charger un script .js se trouvant dans un autre répertoire de travail, vous devez permuter les chaînes "" et "':

my_script='../json-mod.js'
echo `node -pe "JSON.stringify(require('$my_script'))"`
1
Alexander Mills

Utilisez json5 (chargeur) voir https://json5.org/ - exemple (par json5)

{
  lineBreaks: "Look, Mom! \
No \\n's!",
}
0
Lacom