754 Stimmen

YAML: Brauche ich Anführungszeichen für Zeichenfolgen in YAML?

Ich versuche, ein YAML-Wörterbuch für die Internationalisierung eines Rails-Projekts zu schreiben. Ich bin jedoch ein wenig verwirrt, da ich in einigen Dateien Zeichenfolgen in doppelten Anführungszeichen und in einigen ohne sehe. Ein paar Punkte zu beachten:

  • Beispiel 1 - alle Zeichenfolgen verwenden doppelte Anführungszeichen;
  • Beispiel 2 - keine Zeichenfolgen (außer den letzten beiden) verwenden Anführungszeichen;
  • das YAML-Kochbuch sagt: Das Einfassen von Zeichenfolgen in doppelte Anführungszeichen ermöglicht es Ihnen, Escapes zu verwenden, um ASCII- und Unicode-Zeichen darzustellen. Bedeutet das, dass ich doppelte Anführungszeichen nur verwenden muss, wenn ich bestimmte Zeichen escapen möchte? Wenn ja - warum verwenden sie in Beispiel 1 überall doppelte Anführungszeichen - nur aus Gründen der Einheitlichkeit / stilistischen Gründen?
  • die letzten beiden Zeilen von Beispiel 2 verwenden ! - das nicht spezifische Tag, während die letzten beiden Zeilen von Beispiel 1 dies nicht tun - und beide funktionieren.

Meine Frage lautet: Was sind die Regeln für den Einsatz der verschiedenen Arten von Anführungszeichen in YAML?

Könnte man sagen, dass:

  • im Allgemeinen keine Anführungszeichen benötigt werden;
  • verwenden Sie doppelte Anführungszeichen, wenn Sie Zeichen escapen möchten;
  • verwenden Sie ! mit einfachen Anführungszeichen, wenn... ?!?

1001voto

Mark Berry Punkte 16023

Nach einer kurzen Überprüfung des im Frage verwendeten YAML-Kochbuchs und einigen Tests hier ist meine Interpretation:

  • Im Allgemeinen benötigen Sie keine Anführungszeichen.
  • Verwenden Sie Anführungszeichen, um einen String zu erzwingen, z.B. wenn Ihr Schlüssel oder Wert 10 ist, aber Sie möchten, dass er einen String und nicht eine Fixnum zurückgibt, schreiben Sie '10' oder "10".
  • Verwenden Sie Anführungszeichen, wenn Ihr Wert Sonderzeichen enthält (z.B. :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, \).
  • Einfache Anführungszeichen erlauben es Ihnen, fast jedes Zeichen in Ihren String zu setzen, und versuchen nicht, Escape-Codes zu parsen. '\n' würde als der String \n zurückgegeben.
  • Doppelte Anführungszeichen parsen Escape-Codes. "\n" würde als Zeilenumbruch-Zeichen zurückgegeben.
  • Das Ausrufezeichen führt eine Methode ein, z.B. !ruby/sym um ein Ruby-Symbol zurückzugeben.

Mir scheint, dass der beste Ansatz wäre, keine Anführungszeichen zu verwenden, es sei denn, Sie müssen, und dann Einzelanführungszeichen zu verwenden, es sei denn, Sie möchten explizit Escape-Codes verarbeiten.

Aktualisierung

"Ja" und "Nein" sollten in Anführungszeichen (einfach oder doppelt) eingeschlossen werden, sonst werden sie als TrueClass- und FalseClass-Werte interpretiert:

en:
  yesno:
    'yes': 'Ja'
    'no': 'Nein'

88voto

wombatonfire Punkte 3514

Während Marks Antwort schön zusammenfasst, wann die Anführungszeichen gemäß den YAML-Sprachregeln erforderlich sind, denke ich, dass sich viele der Entwickler/Administratoren fragen, wenn sie mit Strings in YAML arbeiten, "was soll meine Faustregel für den Umgang mit den Strings sein?"

Es mag subjektiv klingen, aber die Anzahl der Regeln, die Sie sich merken müssen, wenn Sie die Anführungszeichen nur verwenden wollen, wenn sie wirklich gemäß den Sprachspezifikationen benötigt werden, ist für eine so einfache Sache wie die Spezifizierung eines der häufigsten Datentypen etwas übermäßig. Verstehen Sie mich nicht falsch, Sie werden sie sich nach und nach merken, wenn Sie regelmäßig mit YAML arbeiten, aber was ist, wenn Sie es nur gelegentlich verwenden und kein Automatismus für das Schreiben von YAML entwickelt haben? Wollen Sie wirklich Zeit damit verbringen, sich an alle Regeln zu erinnern, nur um den String richtig zu spezifizieren?

Der ganze Sinn der "Faustregel" ist es, die kognitiven Ressourcen zu sparen und eine häufige Aufgabe ohne darüber nachzudenken zu erledigen. Unsere "CPU"-Zeit könnte argumentativ für etwas Nützlicheres verwendet werden als für die korrekte Bearbeitung der Strings.

Von diesem - rein praktischen - Standpunkt aus denke ich, dass die beste Faustregel ist, die Strings in einfachen Anführungszeichen zu setzen. Die Überlegung dahinter:

  • Einfach angeführte Strings funktionieren für alle Szenarien, außer wenn Sie Escape-Sequenzen verwenden müssen.
  • Das einzige Sonderzeichen, das Sie in einem einfach angeführten String behandeln müssen, ist das einfache Anführungszeichen selbst.

Das sind nur 2 Regeln, an die sich ein gelegentlicher YAML-Benutzer erinnern muss, um den kognitiven Aufwand zu minimieren.

64voto

F1ko Punkte 2248

Es gab bereits einige großartige Antworten auf diese Frage. Allerdings möchte ich sie erweitern und etwas Kontext aus der neuen offiziellen YAML v1.2.2 Spezifikation (veröffentlicht am 1. Oktober 2021) geben, die die "wahre Quelle" für alles rund um YAML ist.

Es gibt drei verschiedene Stile, die verwendet werden können, um Strings darzustellen, von denen jeder seine eigenen Vor- und Nachteile hat:

YAML bietet drei Fließtext-Skalierungsstile: doppelte Anführungszeichen, einfache Anführungszeichen und einfach (unangegeben). Jeder bietet einen anderen Kompromiss zwischen Lesbarkeit und Ausdruckskraft.

Doppelte Anführungszeichen-Stil:

  • Der Stil mit doppelten Anführungszeichen wird durch umschließende "-Indikatoren festgelegt. Dies ist der einzige Stil, der beliebige Zeichenfolgen durch Verwendung von \-Escape-Sequenzen ausdrücken kann. Dies geht jedoch auf Kosten des Erfordernisses, die \- und "-Zeichen zu escapen.

Einfache Anführungszeichen-Stil:

  • Der Stil mit einfachen Anführungszeichen wird durch umschließende '-Indikatoren festgelegt. Daher müssen diese Zeichen innerhalb einer einfachen Skalarzeichenfolge wiederholt werden. Dies ist die einzige Form des Escapings, das bei einfachen Anführungszeichen durchgeführt wird. Insbesondere können die Zeichen \ und " frei verwendet werden. Dadurch werden einfache Textstellen auf druckbare Zeichen beschränkt. Außerdem ist es nur möglich, eine lange Zeile mit einfachen Anführungszeichen an einem Leerzeichen zu unterbrechen, das von Nicht-Leerzeichen umgeben ist.

Einfacher (unangegebener) Stil:

  • Der einfache (unangegebene) Stil hat keine Identifizierungsindikatoren und bietet keine Form des Escapings. Daher handelt es sich um den lesbarsten, am stärksten eingeschränkten und am stärksten kontextsensitiven Stil. Neben einem eingeschränkten Zeichensatz darf ein einfacher Skalar nicht leer sein oder führende oder abschließende Leerzeichen enthalten. Es ist nur möglich, eine lange einfache Zeile an einem Leerzeichen zu unterbrechen, das von Nicht-Leerzeichen umgeben ist. Einfache Skalare dürfen nicht mit den meisten Indikatoren beginnen, da dies zu Mehrdeutigkeiten mit anderen YAML-Konstruktionen führen würde. Die Indikatoren :, ? und - können jedoch als erstes Zeichen verwendet werden, wenn ihnen ein Nicht-Leerzeichen „sicher“ folgt, da dies keine Mehrdeutigkeit verursacht.

Zusammengefasst (TL;DR)

Mit anderen Worten, nach der offiziellen YAML-Spezifikation sollte man:

  • Immer den unangegebenen Stil verwenden, wenn dies möglich ist, da er am lesbarsten ist.
  • Verwenden Sie den einfachen Anführungszeichen-Stil ('), wenn Zeichen wie " und \ innerhalb der Zeichenfolge verwendet werden, um das Escaping zu vermeiden und damit die Lesbarkeit zu verbessern.
  • Verwenden Sie den doppelten Anführungszeichen-Stil ("), wenn die ersten beiden Optionen nicht ausreichen, z.B. in Szenarien, in denen komplexere Zeilenumbrüche erforderlich sind oder nicht-druckbare Zeichen benötigt werden.

21voto

Saiten in yaml müssen nur dann in Anführungszeichen stehen, wenn (der Anfang) des Werts als Datentyp missverstanden werden könnte oder wenn der Wert ein ":" enthält (weil es als Schlüssel missverstanden werden könnte).

Zum Beispiel

foo: '{{ bar }}'

braucht Anführungszeichen, weil es als Datentyp dict missverstanden werden könnte, aber

foo: barbaz{{ bam }}

braucht keine, da es nicht mit einem kritischen Zeichen beginnt. Als nächstes,

foo: '123'

braucht Anführungszeichen, weil es als Datentyp int missverstanden werden könnte, aber

foo: bar1baz234
bar: 123baz

nicht, weil es nicht als int missverstanden werden kann

foo: 'yes'

braucht Anführungszeichen, weil es als Datentyp bool missverstanden werden könnte

foo: "bar:baz:bam"

braucht Anführungszeichen, weil der Wert als Schlüssel missverstanden werden könnte.

Dies sind nur Beispiele. Die Verwendung von yamllint hilft dabei, Werte nicht mit einem falschen Token zu beginnen

foo@bar:/tmp$ yamllint test.yaml 
test.yaml
  3:4       error    syntax error: found character '@' that cannot start any token (syntax)

und ist ein Muss, wenn man produktiv mit yaml arbeiten möchte.

Alle Zeichenfolgen wie von einigen vorgeschlagen zu zitieren, ist wie Klammern in Python zu verwenden. Es ist schlechte Praxis, schadet der Lesbarkeit und wirft das schöne Feature weg, Zeichenfolgen nicht zitieren zu müssen.

3voto

Promise Preston Punkte 15324

Ich hatte diese Bedenken, als ich an einer Rails-Anwendung mit Docker gearbeitet habe.

Mein bevorzugter Ansatz besteht im Allgemeinen darin, keine Anführungszeichen zu verwenden. Dies schließt das Verwenden von Anführungszeichen für Folgendes ein:

  • Variablen wie ${RAILS_ENV}
  • Werte, die durch einen Doppelpunkt (:) getrennt sind, wie postgres-log:/var/log/postgresql
  • Andere Zeichenkettenwerte

Ich verwende jedoch doppelte Anführungszeichen für ganzzahlige Werte, die in Zeichenketten umgewandelt werden müssen, wie:

  • Docker-Compose-Versionen wie version: "3.8"
  • Portnummern wie "8080:8080"
  • Image "traefik:v2.2.1"

Für spezielle Fälle wie Booleans, Kommazahlen, Ganzzahlen und andere Fälle, in denen das Verwenden von doppelten Anführungszeichen für die Eingabewerte als Zeichenketten interpretiert werden könnte, verwenden Sie bitte keine doppelten Anführungszeichen.

Hier ist eine Beispielsdatei docker-compose.yml, um dieses Konzept zu erläutern:

version: "3"

services:
  traefik:
    image: "traefik:v2.2.1"
    command:
      - --api.insecure=true # In der Produktion nicht verwenden
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

Das ist alles.

Ich hoffe, das hilft

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X