it-swarm.com.de

TAB kann in JSON-Dateien nicht analysiert werden

Beim Laden von JSON-Dateien, die das Zeichen TAB enthalten, tritt ein Problem mit der Analyse auf. 

Wenn ich zu http://jsonlint.com/ gehe und den Teil mit dem TAB-Zeichen eingebe:

{
    "My_String": "Foo bar.  Bar foo."
}

Der Validator beschwert sich mit:

Parse error on line 2:
{    "My_String": "Foo bar. Bar foo."
------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

Dies ist buchstäblich ein Kopieren/Einfügen des anstößigen JSON-Textes. 

Ich habe versucht, diese Datei mit json und simplejson ohne Erfolg zu laden. Wie kann ich das richtig laden? Soll ich die Datei einfach vorverarbeiten und TAB durch \t oder durch ein Leerzeichen ersetzen? Oder fehlt mir hier irgendetwas?

Aktualisieren:

Hier ist auch ein problematisches Beispiel in simplejson

foo = '{"My_string": "Foo bar.\t Bar foo."}'
simplejson.loads(foo)

JSONDecodeError: Invalid control character '\t' at: line 1 column 24 (char 23)
26
Josh

Vom JSON-Standard :

Unbedeutende Leerzeichen sind vor oder nach einem Token zulässig. Das Whitespace-Zeichen sind: Zeichentabelle (U + 0009), Zeilenvorschub (U + 000A), Wagenrücklauf (U + 000D) und Leerzeichen (U + 0020). Whitespace ist In keinem Token zulässig, außer dass in .__ Speicherplatz zulässig ist. Streicher.

Dies bedeutet, dass ein Literal-Tabulatorzeichen in einer JSON-Zeichenfolge nicht zulässig ist. Sie müssen es als \t(in einer .json-Datei) :

{"My_string": "Foo bar.\t Bar foo."}

Wenn in einem Python-String-Literal json-Text bereitgestellt wird, müssen Sie die Registerkarte durch doppeltes Escape-Zeichen ersetzen:

foo = '{"My_string": "Foo bar.\\t Bar foo."}' # in a Python source

Oder verwenden Sie ein Python-Rohzeichenfolgenliteral:

foo = r'{"My_string": "Foo bar.\t Bar foo."}' # in a Python source
32
jfs

Tabulatoren sind als Begrenzungszeichen für Leerzeichen außerhalb von Werten zulässig, jedoch nicht innerhalb von Zeichenfolgen. Verwenden Sie stattdessen \t.

BEARBEITEN: Aufgrund Ihrer Kommentare sehe ich einige Verwirrung darüber, was eine Registerkarte eigentlich ist ... Das Registerzeichen ist nur ein normales Zeichen, wie 'a' oder '5' oder '.' oder ein beliebiges anderes Zeichen, das Sie durch Drücken einer Taste auf Ihrer Tastatur eingeben. Es beansprucht ein einzelnes Byte, dessen numerischer Wert 9 ist. Es sind keine umgekehrten Schrägstriche oder Kleinbuchstaben beteiligt.

Was bringt den Tab in eine andere Kategorie als 'a' oder '5' oder '.' ist die Tatsache, dass Sie als Mensch, der Ihre Augäpfel verwendet, im Allgemeinen keine Anzeige von Text betrachten und Tabulatorzeichen nicht erkennen oder zählen können. Visuell ist eine Folge von Registerkarten identisch mit einer Folge von (normalerweise größeren, aber immer noch visuell unbestimmten) Leerzeichen.

Um Tabs innerhalb von Text eindeutig für die Computerverarbeitung darzustellen, stehen verschiedene syntaktische Methoden zur Verfügung: "Hey, ein Stück Software! Diesen Junk durch ein Tabulatorzeichen ersetzen, OK?". 

In der Geschichte der Programmiersprachen gab es zwei Hauptansätze: Wenn Sie in die 50er Jahre zurückgehen, haben Sie beide Ansätze nebeneinander, eine in jeder der zwei ältesten Hochsprachen. LISP hatte Zeichenliterale wie #\Tab benannt. Diese wurden konvertiert, sobald sie aus der Programmquelle gelesen wurden. Fortran hatte nur die CHAR-Funktion, die zur Laufzeit aufgerufen wurde und das Zeichen zurückgab, dessen Nummer mit dem Argument übereinstimmt: CHAR(9) gab einen Tabulator zurück. (Wenn es sich wirklich um CHAR(9) und nicht um CHAR(um einen Ausdruck handelt, der auf 9) klappt, könnte dies ein optimierender Compiler feststellen und den Funktionsaufruf zur Kompilierzeit durch ein Tabulatortool ersetzen, wodurch wir uns wieder im anderen Camp befinden .)

Wenn Sie das Sonderzeichen bei beiden Lösungstypen in eine größere Zeichenfolge einfügen möchten, müssen Sie die Verkettung im Allgemeinen selbst vornehmen. Zum Beispiel könnte ein Kind, das BASIC in den 80er Jahren hackt, so etwas schreiben:

10 PRINT "This is a tab ->"; CHR$(9); "<- That was a tab"

Aber einige Sprachen - vor allem die Familie, die mit der Sprache B begann - führten die Möglichkeit ein, diese Zeichen direkt in ein String-Literal einzufügen:

printf("This is a tab -> *t <- That was a tab");

BCPL behielt die *-Syntax bei, aber die nächste Sprache in der Reihe C ersetzte sie durch den Backslash, wahrscheinlich, weil sie viel häufiger literale Sternchen lesen und schreiben mussten als wörtliche Backslashes.

Wie auch immer, eine ganze Reihe von Sprachen, einschließlich Python und Javascript, haben hier die Konventionen von C ausgeliehen oder geerbt. In beiden Sprachen führen die beiden Ausdrücke "\t" und '\t' zu jeweils einer Zeichenfolge mit einem Zeichen, wobei dieses eine Zeichen eine Registerkarte ist. 

JSON basiert auf der Syntax von Javascript, erlaubt jedoch nur eine eingeschränkte Teilmenge davon. Beispielsweise müssen Zeichenfolgen in doppelte Anführungszeichen (") anstelle einzelner Zeichen (') eingeschlossen werden, und in ihnen sind keine Registerkarten zulässig.

Das bedeutet, dass diese Python-Zeichenfolge aus Ihrem Update:

foo = '{"My_string": "Foo bar.\t Bar foo."}'

ist nicht gültig JSON. Der Python-Interpreter verwandelt die \t-Sequenz in ein tatsächliches Tabulatorzeichen, sobald der String gelesen wird - lange bevor der JSON-Prozessor ihn überhaupt sieht. 

Sie können Python anweisen, anstelle eines Tabulatorzeichens ein Literal \t in den String einzufügen, indem Sie den Backslash verdoppeln:

foo = '{"My_string": "Foo bar.\\t Bar foo."}'

Oder Sie können die "rohe" String-Syntax verwenden, die die speziellen Backslash-Sequenzen überhaupt nicht interpretiert:

foo = r'{"My_string": "Foo bar.\t Bar foo."}'

In jedem Fall sieht der JSON-Prozessor eine Zeichenfolge, die einen Backslash gefolgt von einem 't' enthält, und nicht eine Zeichenfolge mit einem Tabulator.

6
Mark Reed

Sie können Tabulatoren within values ​​(anstelle von Whitespace) in JSON-Dateien einschließen, indem Sie sie umleiten. Hier ein Arbeitsbeispiel mit dem Modul json in Python2.7:

>>> import json
>>> obj = json.loads('{"MY_STRING": "Foo\\tBar"}')
>>> obj['MY_STRING']
u'Foo\tBar'
>>> print obj['MY_STRING']
Foo    Bar

Wenn Sie nicht mit dem '\t' umgehen, wird ein Fehler angezeigt:

>>> json.loads('{"MY_STRING": "Foo\tBar"}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 19 (char 18)
4
mdml

Im knotenroten Fluss stehe ich vor demselben Problem:

flow.set("delimiter",'"\t"');

Error:  

{ "status": "ERROR", "result": "Cannot parse config: String: 1: in value for key 'delimiter': JSON does not allow unescaped tab in quoted strings, use a backslash escape" }  

Lösung:

ich habe nur \\t im Code hinzugefügt.

 flow.set("delimiter",'"\\t"');
0
KARTHIKEYAN.A

Nur um meine Erfahrungen zu teilen:

Ich verwende snakemake und eine in Json geschriebene Konfigurationsdatei. Es gibt Registerkarten in der Json-Datei zum Einrücken. TAB sind zu diesem Zweck legal. Es wird jedoch eine Fehlermeldung angezeigt: snakemake.exceptions.WorkflowError: Die Konfigurationsdatei ist kein gültiger JSON- oder YAML-Code. Ich glaube, das ist ein Fehler von Schlangenmake. aber ich könnte falsch liegen. Bitte kommentieren. Nachdem alle TABs durch Leerzeichen ersetzt wurden, ist die Fehlermeldung weg.

0
Kemin Zhou