Warum sich mit einem separaten Validierungsschritt beschäftigen? Die meisten Sprachen haben JSON-Bibliotheken, die JSON analysieren können, und wenn es es analysieren kann, war es gültig. Wenn nicht, wird die Bibliothek es Ihnen mitteilen.
Epcylon
Sie müssen Text analysieren, um ihn zu validieren ...
Ken
3
@mario - Ich weiß nicht ... Ich bin alles für den Missbrauch von Regex und äußerst sympathisch für Ihren Einwand gegen den "Regex muss mit dem regulären" Irrtum übereinstimmen - aber nicht für praktische, arbeitsbezogene Fragen. Die beste Antwort hier ist wirklich Epcylons Kommentar ... (Vielleicht gehört diese Diskussion in den Chat?)
Kobi
1
Ein weiterer praktischer Anwendungsfall ist das Auffinden von JSON-Ausdrücken in einer größeren Zeichenfolge. Wenn Sie einfach fragen möchten, ob diese Zeichenfolge hier ein JSON-Objekt ist, ist eine JSON-Analysebibliothek wahrscheinlich ein besseres Werkzeug. Es können jedoch keine JSON-Objekte in einer größeren Struktur für Sie gefunden werden.
Ja, eine vollständige Regex-Validierung ist möglich.
Die meisten modernen Regex-Implementierungen ermöglichen rekursive Regexpressions, mit denen eine vollständige serialisierte JSON-Struktur überprüft werden kann. Die json.org-Spezifikation macht es ziemlich einfach.
Es funktioniert ziemlich gut in PHP mit den PCRE-Funktionen . Sollte in Perl unverändert funktionieren; und kann sicherlich für andere Sprachen angepasst werden. Auch mit den JSON-Testfällen gelingt es .
Einfachere RFC4627-Überprüfung
Ein einfacherer Ansatz ist die minimale Konsistenzprüfung gemäß RFC4627, Abschnitt 6 . Es ist jedoch nur als Sicherheitstest und grundlegende Vorsichtsmaßnahme gegen Nichtgültigkeit gedacht:
var my_JSON_object =!(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
text.replace(/"(\\.|[^"\\])*"/g,'')))&&eval('('+ text +')');
+1 Es gibt so viel Schlimmes auf der Welt von Leuten, die einfach nicht die Regex-Syntax verstehen und diese als Grund missbrauchen, sie zu hassen :(
NikiC
8
@ Mario, ich bin mir nicht sicher, ob du denkst, ich bin in der Neinsager-Abteilung , aber ich bin es nicht. Beachten Sie, dass Ihre Aussage "Die meisten modernen Regex-Implementierungen erlauben rekursive Regexpressions" höchst umstritten ist. AFAIK, nur Perl, PHP und .NET können rekursive Muster definieren. Ich würde das nicht "am meisten" nennen.
Bart Kiers
3
@ Bart: Ja, das ist zu Recht umstritten. Am ironischsten ist, dass die Javascript-Regex-Engines einen solchen rekursiven Regex nicht zur Überprüfung von JSON verwenden können (oder nur mit aufwändigen Problemumgehungen). Wenn also regex == posix regex ist, ist dies keine Option. Es ist dennoch interessant, dass es mit den zeitgenössischen Implementierungen machbar ist; auch mit wenigen praktischen Anwendungsfällen. (Aber wahr, libpcre ist nicht überall die vorherrschende Engine.) - Auch für die Aufzeichnung: Ich hatte auf ein synthetisches Umkehrabzeichen gehofft, aber wenn Sie nicht ein paar Upvotes für Bandwagon erhalten, wird dies verhindert. : /
Mario
4
Nee. Ich war hinter dem populistischen Abzeichen her, für das ich 20 Stimmen benötige, aber immer noch 10 Stimmen für Ihre Antwort. Im Gegenteil, die Abstimmungen zu Ihrer Frage sind nicht zu meinem Vorteil.
Mario
2
Wenn Sie weiter schauen, hat dieser reguläre Ausdruck viele andere Probleme. Es stimmt mit JSON-Daten überein, aber auch mit einigen Nicht-JSON-Daten. Beispielsweise falsestimmt das einzelne Literal überein, während der JSON-Wert der obersten Ebene entweder ein Array oder ein Objekt sein muss. Es gibt auch viele Probleme im Zeichensatz, die in Zeichenfolgen oder Leerzeichen zulässig sind.
Dolmen
31
Ja, es ist ein weit verbreitetes Missverständnis, dass reguläre Ausdrücke nur mit regulären Sprachen übereinstimmen können . Tatsächlich können die PCRE-Funktionen viel mehr als normale Sprachen übereinstimmen, sie können sogar mit einigen nicht kontextfreien Sprachen übereinstimmen! Der Wikipedia-Artikel über RegExps enthält einen speziellen Abschnitt dazu.
JSON kann mit PCRE auf verschiedene Arten erkannt werden! @mario zeigte eine großartige Lösung mit benannten Untermustern und Rückverweisen . Dann bemerkte er, dass es eine Lösung mit rekursiven Mustern geben sollte(?R) . Hier ist ein Beispiel für einen solchen regulären Ausdruck, der in PHP geschrieben wurde:
$regexString ='"([^"\\\\]*|\\\\["\\\\bfnrt\/]|\\\\u[0-9a-f]{4})*"';
$regexNumber ='-?(?=[1-9]|0(?!\d))\d+(\.\d+)?([eE][+-]?\d+)?';
$regexBoolean='true|false|null';// these are actually copied from Mario's answer
$regex ='/\A('.$regexString.'|'.$regexNumber.'|'.$regexBoolean.'|';//string, number, boolean
$regex.='\[(?:(?1)(?:,(?1))*)?\s*\]|';//arrays
$regex.='\{(?:\s*'.$regexString.'\s*:(?1)(?:,\s*'.$regexString.'\s*:(?1))*)?\s*\}';//objects
$regex.=')\Z/is';
Ich verwende (?1)stattdessen, (?R)weil letzteres auf das gesamte Muster verweist , aber wir haben \Aund \ZSequenzen, die nicht in Untermustern verwendet werden sollten. (?1)Verweise auf den regulären Ausdruck, der durch die äußersten Klammern gekennzeichnet ist (aus diesem Grund ( )beginnt der äußerste nicht mit ?:). So wird der RegExp 268 Zeichen lang :)
Auf jeden Fall sollte dies als "Technologiedemonstration" behandelt werden, nicht als praktische Lösung. In PHP werde ich die JSON-Zeichenfolge mit dem Aufruf der json_decode()Funktion validieren (genau wie bei @Epcylon angegeben). Wenn ich werde verwenden , dass JSON (wenn es bestätigt ist), dann ist dies die beste Methode.
Verwenden \dist gefährlich. In vielen Regexp-Implementierungen \dentspricht die Unicode-Definition einer Ziffer, die nicht nur [0-9]alternative Skripte enthält, sondern diese auch enthält.
Dolmen
@dolmen: Sie haben vielleicht Recht, aber Sie sollten das nicht selbst in die Frage einarbeiten. Es sollte ausreichen, es nur als Kommentar hinzuzufügen.
Dennis Haarbrink
Ich denke, \dstimmt nicht mit Unicode-Nummern in der PHP-Implementierung von PCRE überein. Zum Beispiel wird das ٩Symbol (0x669 arabisch-indizierende Ziffer neun) mit dem Muster abgeglichen, #\p{Nd}#uaber nicht#\d#u
Hrant Khachatrian
@ hrant-khachatrian: nicht, weil du die /uFlagge nicht benutzt hast . JSON ist in UTF-8 codiert. Für einen korrekten regulären Ausdruck sollten Sie dieses Flag verwenden.
Dolmen
1
@dolmen Ich habe den uModifikator verwendet, bitte schauen Sie sich die Muster in meinem vorherigen Kommentar noch einmal an :) Zeichenfolgen, Zahlen und Boolesche Werte stimmen auf der obersten Ebene korrekt überein. Sie können den langen regulären Ausdruck hier einfügen quanetic.com/Regex und versuchen Sie es selbst
Hrant Khachatrian
14
Aufgrund der rekursiven Natur von JSON (verschachtelte {...}-s) ist Regex nicht zur Validierung geeignet. Sicher, einige Regex-Aromen können rekursiv mit Mustern * übereinstimmen (und können daher mit JSON übereinstimmen), aber die resultierenden Muster sind schrecklich anzusehen und sollten niemals im Produktionscode IMO verwendet werden!
* Obwohl viele regex Implementierungen Vorsicht nicht unterstützen rekursive Muster. Von den gängigen Programmiersprachen unterstützen diese rekursive Muster: Perl, .NET, PHP und Ruby 1.9.2
@all down Wähler: "Regex ist nicht geeignet, um es zu validieren" bedeutet nicht, dass bestimmte Regex-Engines dies nicht können (zumindest habe ich das so gemeint). Sicher, einige Regex-Implementierungen können dies , aber jeder, der bei klarem Verstand ist, würde einfach einen JSON-Parser verwenden. Genau wie wenn jemand fragt, wie man ein komplettes Haus mit nur einem Hammer baut, würde ich antworten, dass ein Hammer nicht für den Job geeignet ist, man würde ein komplettes Werkzeugset und Maschinen brauchen. Sicher, jemand mit genügend Ausdauer kann es nur mit dem Hammer tun.
Bart Kiers
1
Dies mag eine gültige Warnung sein, beantwortet aber die Frage nicht . Regex ist möglicherweise nicht das richtige Werkzeug, aber einige Leute haben keine Wahl. Wir sind an ein Anbieterprodukt gebunden, das die Ausgabe eines Dienstes auswertet, um dessen Zustand zu überprüfen. Die einzige Option, die der Anbieter für die benutzerdefinierte Integritätsprüfung bereitstellt, ist ein Webformular, das einen regulären Ausdruck akzeptiert. Das Lieferantenprodukt, das den Servicestatus bewertet, unterliegt nicht der Kontrolle meines Teams. Für uns ist die Bewertung von JSON mit Regex nun eine Voraussetzung, daher ist eine Antwort mit "ungeeignet" nicht realisierbar. (Ich habe dich immer noch nicht abgelehnt.)
John Deters
11
Ich habe die Antwort von @ mario ausprobiert, aber sie hat bei mir nicht funktioniert, da ich die Testsuite von JSON.org ( Archiv ) heruntergeladen habe und 4 Tests fehlgeschlagen sind (fail1.json, fail18.json, fail25.json, fail27. json).
Ich habe die Fehler untersucht und herausgefunden, dass dies fail1.jsontatsächlich korrekt ist (gemäß dem Hinweis des Handbuchs und der gültigen RFC-7159- Zeichenfolge ist auch ein gültiger JSON). Die Datei fail18.jsonwar auch nicht der Fall, da sie tatsächlich korrekt tief verschachtelten JSON enthält:
Dies stimmt auch nur mit JSON-Werten (Zeichenfolgen, Booleschen Werten und Zahlen) überein, bei denen es sich nicht um ein JSON-Objekt / Array handelt.
Kowsikbabu
4
In der Dokumentation zu JSON scheint es, dass der reguläre Ausdruck einfach aus drei Teilen bestehen kann, wenn das Ziel nur darin besteht, die Fitness zu überprüfen:
Die Zeichenfolge beginnt und endet mit entweder []oder{}
[{\[]{1}...[}\]]{1}
und
Das Zeichen ist ein zulässiges JSON-Steuerzeichen (nur eines).
... [,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]...
oder Der Zeichensatz in a""
... ".*?"...
Alle zusammen:
[{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}
Wenn die JSON-Zeichenfolge newlineZeichen enthält , sollten Sie den singlelineSchalter für Ihre Regex-Variante verwenden, damit er .übereinstimmt newline. Beachten Sie, dass dies nicht bei allen fehlerhaften JSONs fehlschlägt, aber fehlschlägt, wenn die grundlegende JSON-Struktur ungültig ist. Dies ist eine einfache Möglichkeit, eine grundlegende Überprüfung der Integrität durchzuführen, bevor sie an einen Parser übergeben wird.
Der vorgeschlagene reguläre Ausdruck weist in bestimmten Testfällen ein schreckliches Rückverfolgungsverhalten auf. Wenn Sie versuchen, es auf '{"a": false, "b": true, "c": 100, "' diesem unvollständigen JSON auszuführen , wird es angehalten. Beispiel: regex101.com/r/Zzc6sz . Eine einfache Lösung wäre : [{[] {1} ([,: {} [] 0-9. \ - + Eaeflnr-u \ n \ r \ t] | ". *?") + [}]] {1}
Toonijn
@Toonijn Ich habe aktualisiert, um Ihren Kommentar wiederzugeben. Vielen Dank!
CJBarth
3
Ich habe eine Ruby-Implementierung von Marios Lösung erstellt, die funktioniert:
# encoding: utf-8moduleConstants
JSON_VALIDATOR_RE =/(# define subtypes and build up the json syntax, BNF-grammar-style# The {0} is a hack to simply define them as named groups here but not match on them yet# I added some atomic grouping to prevent catastrophic backtracking on invalid inputs(?<number>-?(?=[1-9]|0(?!\d))\d+(\.\d+)?([eE][+-]?\d+)?){0}(?<boolean>true|false|null){0}(?<string>" (?>[^"\\\\]*| \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* "){0}(?<array> \[ (?> \g<json>(?:, \g<json>)*)? \s* \] ){0}(?<pair> \s* \g<string> \s*: \g<json>){0}(?<object> \{ (?> \g<pair>(?:, \g<pair>)*)? \s* \} ){0}(?<json> \s*(?> \g<number>| \g<boolean>| \g<string>| \g<array>| \g<object>) \s*){0})
\A \g<json> \Z
/uix
end########## inline test runningif __FILE__==$PROGRAM_NAME
# supportclassStringdef unindent
gsub(/^#{scan(/^(?!\n)\s*/).min_by{|l|l.length}}/u,"")endendrequire'test/unit'unlessdefined?Test::UnitclassJsonValidationTest<Test::Unit::TestCase
include Constantsdef setup
enddef test_json_validator_simple_string
assert_not_nil %s[{"somedata":5}].match(JSON_VALIDATOR_RE)enddef test_json_validator_deep_string
long_json =<<-JSON.unindent
{"glossary":{"title":"example glossary","GlossDiv":{"id":1918723,"boolean":true,"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}
JSON
assert_not_nil long_json.match(JSON_VALIDATOR_RE)endendend
Die Verwendung von \ d ist gefährlich. In vielen Regexp-Implementierungen entspricht \ d der Unicode-Definition einer Ziffer, die nicht nur [0-9] ist, sondern alternative Skripte enthält. Wenn die Unicode-Unterstützung in Ruby nicht immer noch unterbrochen ist, müssen Sie den regulären Ausdruck in Ihrem Code korrigieren.
Dolmen
Soweit ich weiß, verwendet Ruby PCRE, in dem \ d nicht mit ALLEN Unicode-Definitionen von "Ziffer" übereinstimmt. Oder sagst du, dass es sollte?
Pmarreck
Nur dass es nicht so ist. Falsch positiv: "\ x00", [Richtig]. Falsch negativ: "\ u0000", "\ n". Hängt an: "[{" ": [{" ": [{" ":" (1000x wiederholt).
nst
Nicht zu schwer, als Testfälle hinzuzufügen und dann den zu passierenden Code zu optimieren. Wie man es schafft, den Stapel nicht mit einer Tiefe von 1000+ zu sprengen, ist jedoch eine ganz andere Sache ...
pmarreck
1
Für "Strings und Zahlen" denke ich, dass der teilweise reguläre Ausdruck für Zahlen:
-?(?:0|[1-9]\d*)(?:\.\d+)(?:[eE][+-]\d+)?
sollte stattdessen sein:
-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+\-]?\d+)?
da der Dezimalteil der Zahl optional ist und es wahrscheinlich auch sicherer ist, das -Symbol zu maskieren, [+-]da es eine besondere Bedeutung in Klammern hat
Verwenden \dist gefährlich. In vielen Regexp-Implementierungen \dentspricht die Unicode-Definition einer Ziffer, die nicht nur [0-9]alternative Skripte enthält, sondern diese auch enthält.
Dolmen
Es sieht ein bisschen seltsam aus, dass -0 eine gültige Zahl ist, aber RFC 4627 erlaubt dies und Ihr regulärer Ausdruck entspricht dieser.
Ceving
1
Ein nachfolgendes Komma in einem JSON-Array ließ mein Perl 5.16 hängen, möglicherweise weil es immer wieder zurückverfolgt wurde. Ich musste eine Backtrack-terminierende Direktive hinzufügen:
Auf diese Weise sollte es, sobald es ein Konstrukt identifiziert, das nicht 'optional' ( *oder ?) ist, nicht versuchen, es zurückzuverfolgen, um es als etwas anderes zu identifizieren.
Wenn die von Ihnen verwendete Sprache eine JSON-Bibliothek enthält, versuchen Sie, wie oben beschrieben, die Zeichenfolge zu dekodieren und die Ausnahme / den Fehler abzufangen, wenn dies fehlschlägt! Wenn die Sprache dies nicht tut (hatte gerade einen solchen Fall mit FreeMarker), könnte der folgende reguläre Ausdruck zumindest eine sehr grundlegende Validierung liefern (er wurde geschrieben, damit PHP / PCRE für mehr Benutzer testbar / verwendbar ist). Es ist nicht so narrensicher wie die akzeptierte Lösung, aber auch nicht so beängstigend =):
~^\{\s*\".*\}$|^\[\n?\{\s*\".*\}\n?\]$~s
kurze Erklärung:
// we have two possibilities in case the string is JSON// 1. the string passed is "just" a JSON object, e.g. {"item": [], "anotheritem": "content"}// this can be matched by the following regex which makes sure there is at least a {" at the// beginning of the string and a } at the end of the string, whatever is inbetween is not checked!^\{\s*\".*\}$
// OR (character "|" in the regex pattern)// 2. the string passed is a JSON array, e.g. [{"item": "value"}, {"item": "value"}]// which would be matched by the second part of the pattern above^\[\n?\{\s*\".*\}\n?\]$
// the s modifier is used to make "." also match newline characters (can happen in prettyfied JSON)
Wenn ich etwas verpasst habe, das dies unbeabsichtigt brechen würde, bin ich für Kommentare dankbar!
Mir ist klar, dass dies von vor über 6 Jahren ist. Ich denke jedoch, dass es eine Lösung gibt, die hier niemand erwähnt hat und die viel einfacher ist als Regexing
function isAJSON(string){try{
JSON.parse(string)}catch(e){if(e instanceofSyntaxError)returnfalse;};returntrue;}
Antworten:
Ja, eine vollständige Regex-Validierung ist möglich.
Die meisten modernen Regex-Implementierungen ermöglichen rekursive Regexpressions, mit denen eine vollständige serialisierte JSON-Struktur überprüft werden kann. Die json.org-Spezifikation macht es ziemlich einfach.
Es funktioniert ziemlich gut in PHP mit den PCRE-Funktionen . Sollte in Perl unverändert funktionieren; und kann sicherlich für andere Sprachen angepasst werden. Auch mit den JSON-Testfällen gelingt es .
Einfachere RFC4627-Überprüfung
Ein einfacherer Ansatz ist die minimale Konsistenzprüfung gemäß RFC4627, Abschnitt 6 . Es ist jedoch nur als Sicherheitstest und grundlegende Vorsichtsmaßnahme gegen Nichtgültigkeit gedacht:
quelle
false
stimmt das einzelne Literal überein, während der JSON-Wert der obersten Ebene entweder ein Array oder ein Objekt sein muss. Es gibt auch viele Probleme im Zeichensatz, die in Zeichenfolgen oder Leerzeichen zulässig sind.Ja, es ist ein weit verbreitetes Missverständnis, dass reguläre Ausdrücke nur mit regulären Sprachen übereinstimmen können . Tatsächlich können die PCRE-Funktionen viel mehr als normale Sprachen übereinstimmen, sie können sogar mit einigen nicht kontextfreien Sprachen übereinstimmen! Der Wikipedia-Artikel über RegExps enthält einen speziellen Abschnitt dazu.
JSON kann mit PCRE auf verschiedene Arten erkannt werden! @mario zeigte eine großartige Lösung mit benannten Untermustern und Rückverweisen . Dann bemerkte er, dass es eine Lösung mit rekursiven Mustern geben sollte
(?R)
. Hier ist ein Beispiel für einen solchen regulären Ausdruck, der in PHP geschrieben wurde:Ich verwende
(?1)
stattdessen,(?R)
weil letzteres auf das gesamte Muster verweist , aber wir haben\A
und\Z
Sequenzen, die nicht in Untermustern verwendet werden sollten.(?1)
Verweise auf den regulären Ausdruck, der durch die äußersten Klammern gekennzeichnet ist (aus diesem Grund( )
beginnt der äußerste nicht mit?:
). So wird der RegExp 268 Zeichen lang :)Auf jeden Fall sollte dies als "Technologiedemonstration" behandelt werden, nicht als praktische Lösung. In PHP werde ich die JSON-Zeichenfolge mit dem Aufruf der
json_decode()
Funktion validieren (genau wie bei @Epcylon angegeben). Wenn ich werde verwenden , dass JSON (wenn es bestätigt ist), dann ist dies die beste Methode.quelle
\d
ist gefährlich. In vielen Regexp-Implementierungen\d
entspricht die Unicode-Definition einer Ziffer, die nicht nur[0-9]
alternative Skripte enthält, sondern diese auch enthält.\d
stimmt nicht mit Unicode-Nummern in der PHP-Implementierung von PCRE überein. Zum Beispiel wird das٩
Symbol (0x669 arabisch-indizierende Ziffer neun) mit dem Muster abgeglichen,#\p{Nd}#u
aber nicht#\d#u
/u
Flagge nicht benutzt hast . JSON ist in UTF-8 codiert. Für einen korrekten regulären Ausdruck sollten Sie dieses Flag verwenden.u
Modifikator verwendet, bitte schauen Sie sich die Muster in meinem vorherigen Kommentar noch einmal an :) Zeichenfolgen, Zahlen und Boolesche Werte stimmen auf der obersten Ebene korrekt überein. Sie können den langen regulären Ausdruck hier einfügen quanetic.com/Regex und versuchen Sie es selbstAufgrund der rekursiven Natur von JSON (verschachtelte
{...}
-s) ist Regex nicht zur Validierung geeignet. Sicher, einige Regex-Aromen können rekursiv mit Mustern * übereinstimmen (und können daher mit JSON übereinstimmen), aber die resultierenden Muster sind schrecklich anzusehen und sollten niemals im Produktionscode IMO verwendet werden!* Obwohl viele regex Implementierungen Vorsicht nicht unterstützen rekursive Muster. Von den gängigen Programmiersprachen unterstützen diese rekursive Muster: Perl, .NET, PHP und Ruby 1.9.2
quelle
Ich habe die Antwort von @ mario ausprobiert, aber sie hat bei mir nicht funktioniert, da ich die Testsuite von JSON.org ( Archiv ) heruntergeladen habe und 4 Tests fehlgeschlagen sind (fail1.json, fail18.json, fail25.json, fail27. json).
Ich habe die Fehler untersucht und herausgefunden, dass dies
fail1.json
tatsächlich korrekt ist (gemäß dem Hinweis des Handbuchs und der gültigen RFC-7159- Zeichenfolge ist auch ein gültiger JSON). Die Dateifail18.json
war auch nicht der Fall, da sie tatsächlich korrekt tief verschachtelten JSON enthält:Also noch zwei Dateien übrig:
fail25.json
undfail27.json
:und
Beide enthalten ungültige Zeichen. Also habe ich das Muster wie folgt aktualisiert (String-Untermuster aktualisiert):
Jetzt können alle rechtlichen Tests von json.org bestanden werden.
quelle
In der Dokumentation zu JSON scheint es, dass der reguläre Ausdruck einfach aus drei Teilen bestehen kann, wenn das Ziel nur darin besteht, die Fitness zu überprüfen:
[]
oder{}
[{\[]{1}
...[}\]]{1}
[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]
...""
".*?"
...Alle zusammen:
[{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}
Wenn die JSON-Zeichenfolge
newline
Zeichen enthält , sollten Sie densingleline
Schalter für Ihre Regex-Variante verwenden, damit er.
übereinstimmtnewline
. Beachten Sie, dass dies nicht bei allen fehlerhaften JSONs fehlschlägt, aber fehlschlägt, wenn die grundlegende JSON-Struktur ungültig ist. Dies ist eine einfache Möglichkeit, eine grundlegende Überprüfung der Integrität durchzuführen, bevor sie an einen Parser übergeben wird.quelle
Ich habe eine Ruby-Implementierung von Marios Lösung erstellt, die funktioniert:
quelle
Für "Strings und Zahlen" denke ich, dass der teilweise reguläre Ausdruck für Zahlen:
sollte stattdessen sein:
da der Dezimalteil der Zahl optional ist und es wahrscheinlich auch sicherer ist, das
-
Symbol zu maskieren,[+-]
da es eine besondere Bedeutung in Klammern hatquelle
\d
ist gefährlich. In vielen Regexp-Implementierungen\d
entspricht die Unicode-Definition einer Ziffer, die nicht nur[0-9]
alternative Skripte enthält, sondern diese auch enthält.Ein nachfolgendes Komma in einem JSON-Array ließ mein Perl 5.16 hängen, möglicherweise weil es immer wieder zurückverfolgt wurde. Ich musste eine Backtrack-terminierende Direktive hinzufügen:
Auf diese Weise sollte es, sobald es ein Konstrukt identifiziert, das nicht 'optional' (
*
oder?
) ist, nicht versuchen, es zurückzuverfolgen, um es als etwas anderes zu identifizieren.quelle
Wenn die von Ihnen verwendete Sprache eine JSON-Bibliothek enthält, versuchen Sie, wie oben beschrieben, die Zeichenfolge zu dekodieren und die Ausnahme / den Fehler abzufangen, wenn dies fehlschlägt! Wenn die Sprache dies nicht tut (hatte gerade einen solchen Fall mit FreeMarker), könnte der folgende reguläre Ausdruck zumindest eine sehr grundlegende Validierung liefern (er wurde geschrieben, damit PHP / PCRE für mehr Benutzer testbar / verwendbar ist). Es ist nicht so narrensicher wie die akzeptierte Lösung, aber auch nicht so beängstigend =):
kurze Erklärung:
Wenn ich etwas verpasst habe, das dies unbeabsichtigt brechen würde, bin ich für Kommentare dankbar!
quelle
Regex, der einfaches JSON validiert, nicht JSONArray
es validiert Schlüssel (Zeichenfolge): Wert (Zeichenfolge, Ganzzahl, [{Schlüssel: Wert}, {Schlüssel: Wert}], {Schlüssel: Wert})
Beispieldaten, die von diesem JSON validiert werden
quelle
Hier mein regulärer Ausdruck für die Validierung der Zeichenfolge:
Wurde unter Verwendung des ursprünglichen Syntaxdiagramms geschrieben .
quelle
Mir ist klar, dass dies von vor über 6 Jahren ist. Ich denke jedoch, dass es eine Lösung gibt, die hier niemand erwähnt hat und die viel einfacher ist als Regexing
quelle