Regex do walidacji JSON


90

Szukam Regex, który pozwala mi zweryfikować json.

Jestem bardzo nowy w Regex's i wiem wystarczająco dużo, że parsowanie z Regex jest złe, ale czy można go użyć do walidacji?


31
Po co zawracać sobie głowę oddzielnym krokiem weryfikacji? Większość języków ma biblioteki JSON, które mogą analizować JSON, a jeśli mogą go analizować, były prawidłowe. Jeśli nie, biblioteka ci powie.
Epcylon

Musisz przeanalizować tekst, aby go zweryfikować ...
Ken

3
@mario - nie wiem ... Jestem za nadużywaniem wyrażenia regularnego i bardzo przychylam się do Twojego sprzeciwu wobec błędu „wyrażenie regularne musi pasować do zwykłego” - ale nie w kwestiach praktycznych, związanych z pracą. Najlepszą odpowiedzią tutaj jest tak naprawdę komentarz Epcylona ... (może ta dyskusja należy do czatu?)
Kobi

1
Innym praktycznym przypadkiem użycia jest znajdowanie wyrażeń JSON w większym ciągu. Jeśli chcesz po prostu zapytać „czy ten ciąg jest tutaj obiektem JSON”, to tak, biblioteka analizująca JSON jest prawdopodobnie lepszym narzędziem. Ale nie może znaleźć obiektów JSON w większej strukturze.
Mark Amery,

1
To nie jest odpowiedź, ale możesz użyć tej części biblioteki JSON-js firmy Crockford . Używa 4 wyrażeń regularnych i łączy je w sprytny sposób.
imgx64

Odpowiedzi:


184

Tak, pełna weryfikacja wyrażeń regularnych jest możliwa.

Większość nowoczesnych implementacji regex pozwala na rekurencyjne wyrażenia rekurencyjne, które mogą zweryfikować pełną zserializowaną strukturę JSON. Specyfikacja json.org czyni to całkiem prostym.

$pcre_regex = '
  /
  (?(DEFINE)
     (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )    
     (?<boolean>   true | false | null )
     (?<string>    " ([^"\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
     (?<array>     \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] )
     (?<pair>      \s* (?&string) \s* : (?&json)  )
     (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} )
     (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
  )
  \A (?&json) \Z
  /six   
';

Działa całkiem dobrze w PHP z funkcjami PCRE . Powinien działać niezmodyfikowany w Perlu; iz pewnością można je dostosować do innych języków. Udaje się również z przypadkami testowymi JSON .

Prostsza weryfikacja RFC4627

Prostszym podejściem jest sprawdzenie minimalnej spójności, jak określono w dokumencie RFC4627, sekcja 6 . Jest to jednak przeznaczone tylko jako test bezpieczeństwa i podstawowe zabezpieczenie przed utratą ważności:

  var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
         text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
     eval('(' + text + ')');

22
+1 Jest tak wiele zła na świecie od ludzi, którzy po prostu nie
rozumieją składni wyrażeń

8
@mario, nie jestem pewien, czy myślisz, że jestem w dziale-krytyków , ale tak nie jest. Zwróć uwagę, że twoje stwierdzenie „Większość nowoczesnych implementacji regexów pozwala na rekurencyjne wyrażenia rekurencyjne” jest wysoce dyskusyjne. AFAIK, tylko Perl, PHP i .NET mają możliwość definiowania wzorców rekurencyjnych. Nie nazwałbym tego „najbardziej”.
Bart Kiers

3
@Bart: Tak, to słusznie dyskusyjne. Jak na ironię, silniki wyrażeń regularnych Javascript nie mogą używać takiego rekurencyjnego wyrażenia regularnego do weryfikacji JSON (lub tylko z wyszukanymi obejściami). Więc jeśli regex == posix regex, to nie jest opcja. Niemniej jednak interesujące jest, że jest to wykonalne we współczesnych implementacjach; nawet z kilkoma praktycznymi przypadkami użycia. (Ale prawda, libpcre nie jest powszechnym silnikiem wszędzie.) - Również dla przypomnienia: miałem nadzieję na syntetyczną odznakę odwrócenia, ale twoje nie zdobycie kilku pozytywnych głosów utrudnia to. : /
mario

4
Nie. Byłem za odznaką populistów, na którą potrzebuję 20 głosów, ale nadal 10 głosów na twoją odpowiedź. Wręcz przeciwnie, głosy przeciwne w twoim pytaniu nie są dla mnie korzystne.
mario,

2
Patrząc dalej, to wyrażenie regularne ma wiele innych problemów. Pasuje do danych JSON, ale niektóre dane inne niż JSON pasują również. Na przykład pojedynczy literał falsepasuje, podczas gdy wartość JSON najwyższego poziomu musi być tablicą lub obiektem. Ma również wiele problemów w zestawach znaków dozwolonych w łańcuchach lub spacjach.
dolmen,

32

Tak, powszechne jest błędne przekonanie, że wyrażenia regularne mogą pasować tylko do zwykłych języków . W rzeczywistości funkcje PCRE mogą dopasować znacznie więcej niż zwykłe języki , mogą pasować nawet do niektórych języków niekontekstowych! Artykuł Wikipedii na temat RegExps zawiera specjalną sekcję na ten temat.

JSON można rozpoznać za pomocą PCRE na kilka sposobów! @mario pokazało jedno świetne rozwiązanie, używając nazwanych wzorców podrzędnych i odniesień wstecznych . Następnie zauważył, że powinno być rozwiązanie wykorzystujące wzorce rekurencyjne (?R) . Oto przykład takiego wyrażenia regularnego napisanego w PHP:

$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';

Używam (?1)zamiast, (?R)ponieważ ten ostatni odwołuje się do całego wzorca, ale mamy \Ai \Zsekwencje, które nie powinny być używane wewnątrz wzorców podrzędnych. (?1)odniesienia do wyrażenia regularnego oznaczone skrajnymi nawiasami (dlatego najbardziej zewnętrzne ( )nie zaczyna się od ?:). Tak więc wyrażenie RegExp ma długość 268 znaków :)

/\A("([^"\\]*|\\["\\bfnrt\/]|\\u[0-9a-f]{4})*"|-?(?=[1-9]|0(?!\d))\d+(\.\d+)?([eE][+-]?\d+)?|true|false|null|\[(?:(?1)(?:,(?1))*)?\s*\]|\{(?:\s*"([^"\\]*|\\["\\bfnrt\/]|\\u[0-9a-f]{4})*"\s*:(?1)(?:,\s*"([^"\\]*|\\["\\bfnrt\/]|\\u[0-9a-f]{4})*"\s*:(?1))*)?\s*\})\Z/is

Zresztą należy to traktować jako „demonstrację technologii”, a nie praktyczne rozwiązanie. W PHP json_decode()sprawdzę ciąg JSON przez wywołanie funkcji (tak jak zauważył @Epcylon). Jeśli mam zamiar używać tego formatu JSON (jeśli jest zweryfikowany), to jest to najlepsza metoda.


1
Używanie \djest niebezpieczne. W wielu implementacjach regexp \ddopasowuje definicję Unicode cyfry, która nie jest tylko, [0-9]ale zamiast tego zawiera alternatywne skrypty.
dolmen,

@dolmen: możesz mieć rację, ale nie powinieneś sam tego edytować w pytaniu. Wystarczy dodać go jako komentarz.
Dennis Haarbrink

Myślę, że \dnie pasuje do numerów Unicode w implementacji PCRE w PHP. Na przykład ٩symbol (0x669 arabsko-indyjska cyfra dziewięć) zostanie dopasowany za pomocą wzorca, #\p{Nd}#uale nie#\d#u
Hrant Khachatrian

@ hrant-khachatrian: nie, ponieważ nie użyłeś /uflagi. JSON jest zakodowany w UTF-8. Aby uzyskać prawidłowe wyrażenie regularne, powinieneś użyć tej flagi.
dolmen,

1
@dolmen Użyłem umodyfikatora, spójrz jeszcze raz na wzorce w moim poprzednim komentarzu :) Ciągi znaków, liczby i wartości logiczne SĄ poprawnie dopasowane na najwyższym poziomie. Możesz wkleić długie wyrażenie regularne tutaj quanetic.com/Regex i spróbować samemu
Hrant Khachatrian

14

Ze względu na rekursywny charakter formatu JSON (zagnieżdżone {...}-s) wyrażenie regularne nie nadaje się do jego weryfikacji. Jasne, niektóre odmiany wyrażeń regularnych mogą rekursywnie dopasowywać wzorce * (i dlatego mogą pasować do JSON), ale wynikowe wzorce są straszne i nigdy nie powinny być używane w produkcyjnym kodzie IMO!

* Uważaj jednak, wiele implementacji regex nie obsługuje wzorców rekurencyjnych. Spośród popularnych języków programowania obsługują one wzorce rekurencyjne: Perl, .NET, PHP i Ruby 1.9.2



16
@ wszystkich głosujących w dół: „wyrażenie regularne nie nadaje się do sprawdzania poprawności” nie oznacza, że ​​niektóre silniki wyrażeń regularnych nie mogą tego zrobić (przynajmniej to miałem na myśli). Jasne, niektóre implementacje wyrażeń regularnych mogą , ale każdy przy zdrowych zmysłach użyłby po prostu parsera JSON. Tak jak gdyby ktoś zapytał, jak zbudować cały dom za pomocą samego młotka, odpowiedziałbym, że młotek nie nadaje się do tego zadania, potrzebujesz kompletnego zestawu narzędzi i maszyn. Jasne, ktoś z odpowiednią wytrzymałością może to zrobić tylko młotkiem.
Bart Kiers

1
Może to być ważne ostrzeżenie, ale nie odpowiada na pytanie . Regex może nie być właściwym narzędziem, ale niektórzy ludzie nie mają wyboru. Jesteśmy zamknięci w produkcie dostawcy, który ocenia dane wyjściowe usługi w celu sprawdzenia jej kondycji, a jedyną opcją oferowaną przez dostawcę do niestandardowego sprawdzania kondycji jest formularz internetowy, który akceptuje wyrażenie regularne. Produkt dostawcy, który ocenia stan usługi, nie jest pod kontrolą mojego zespołu. Dla nas ocena JSON za pomocą wyrażenia regularnego jest teraz wymogiem, dlatego odpowiedź „nieodpowiedni” nie jest możliwa. (Nadal cię nie zagłosowałem.)
John Deters

12

Wypróbowałem odpowiedź @ mario, ale nie zadziałała, ponieważ pobrałem pakiet testów z JSON.org ( archiwum ) i były 4 nieudane testy (fail1.json, fail18.json, fail25.json, fail27. json).

Zbadałem błędy i odkryłem, że fail1.json jest to rzeczywiście poprawne (zgodnie z uwagą instrukcji i prawidłowym ciągiem znaków RFC-7159 jest również prawidłowym JSON). Plik też fail18.jsonnie był przypadkiem, ponieważ zawiera faktycznie poprawne głęboko zagnieżdżone JSON:

[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]

Zostały więc dwa pliki: fail25.jsoni fail27.json:

["  tab character   in  string  "]

i

["line
break"]

Obie zawierają nieprawidłowe znaki. Więc zaktualizowałem wzorzec w ten sposób (zaktualizowano podwzór łańcucha):

$pcreRegex = '/
          (?(DEFINE)
             (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )
             (?<boolean>   true | false | null )
             (?<string>    " ([^"\n\r\t\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
             (?<array>     \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] )
             (?<pair>      \s* (?&string) \s* : (?&json)  )
             (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} )
             (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
          )
          \A (?&json) \Z
          /six';

Więc teraz wszystkie testy prawne z json.org można zaliczyć.


Spowoduje to również dopasowanie tylko wartości JSON (ciągów znaków, wartości logicznych i liczb), które nie są obiektem / tablicą JSON.
kowsikbabu

4

Patrząc na dokumentację JSON , wydaje się, że wyrażenie regularne może składać się po prostu z trzech części, jeśli celem jest tylko sprawdzenie sprawności:

  1. Ciąg zaczyna się i kończy na []lub{}
    • [{\[]{1}...[}\]]{1}
  2. i
    1. Znak to dozwolony znak kontrolny JSON (tylko jeden)
      • ... [,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]...
    2. lub Zestaw znaków zawartych w pliku""
      • ... ".*?"...

Wszyscy razem: [{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}

Jeśli ciąg JSON zawiera newlineznaki, powinieneś użyć singlelineprzełącznika w swoim stylu wyrażenia regularnego, aby .pasował newline. Należy pamiętać, że nie zakończy się to niepowodzeniem w przypadku wszystkich złych JSON, ale zakończy się niepowodzeniem, jeśli podstawowa struktura JSON jest nieprawidłowa, co jest prostym sposobem przeprowadzenia podstawowej weryfikacji poprawności przed przekazaniem jej do parsera.


1
Sugerowane wyrażenie regularne ma okropne zachowanie podczas wycofywania się w niektórych przypadkach testowych. Jeśli spróbujesz uruchomić go na '{"a": false, "b": true, "c": 100, "' tym niekompletnym pliku json, zostanie zatrzymany. Przykład: regex101.com/r/Zzc6sz . Prostą poprawką byłoby : [{[] {1} ([,: {} [] 0-9. \ - + Eaeflnr-u \ n \ r \ t] | ". *?") + [}]] {1}
Toonijn

@Toonijn Zaktualizowałem, aby odzwierciedlić Twój komentarz. Dzięki!
cjbarth

3

Stworzyłem implementację Ruby rozwiązania Mario, która działa:

# encoding: utf-8

module Constants
  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 running
if __FILE__==$PROGRAM_NAME

  # support
  class String
    def unindent
      gsub(/^#{scan(/^(?!\n)\s*/).min_by{|l|l.length}}/u, "")
    end
  end

  require 'test/unit' unless defined? Test::Unit
  class JsonValidationTest < Test::Unit::TestCase
    include Constants

    def setup

    end

    def test_json_validator_simple_string
      assert_not_nil %s[ {"somedata": 5 }].match(JSON_VALIDATOR_RE)
    end

    def 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)
    end

  end
end

Używanie \ d jest niebezpieczne. W wielu implementacjach wyrażeń regularnych \ d odpowiada definicji cyfry w standardzie Unicode, która nie jest tylko [0-9], ale zawiera alternatywne skrypty. Więc jeśli obsługa Unicode w Rubim nie jest nadal zepsuta, musisz naprawić wyrażenie regularne w swoim kodzie.
dolmen

O ile wiem, Ruby używa PCRE, w którym \ d nie pasuje do WSZYSTKICH definicji "cyfry" w formacie Unicode. A może mówisz, że powinno?
pmarreck

Tyle że tak nie jest. Fałszywie dodatni: „\ x00”, [True]. Fałszywie ujemny: „\ u0000”, „\ n”. Zawiesza się: "[{" ": [{" ": [{" ":" (powtórzono 1000x).
nst

Nietrudno dodać jako przypadki testowe, a następnie zmodyfikować kod, aby przejść. Jak to zrobić, aby nie wysadzić stosu o głębokości 1000+, to zupełnie inna sprawa ...
pmarreck

1

Myślę, że w przypadku „ciągów znaków i liczb” częściowe wyrażenie regularne dla liczb:

-?(?:0|[1-9]\d*)(?:\.\d+)(?:[eE][+-]\d+)?

zamiast tego powinno być:

-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+\-]?\d+)?

ponieważ część dziesiętna liczby jest opcjonalna, a także prawdopodobnie bezpieczniej jest uciec przed -symbolem, [+-]ponieważ ma on specjalne znaczenie w nawiasach


Używanie \djest niebezpieczne. W wielu implementacjach regexp \ddopasowuje definicję Unicode cyfry, która nie jest tylko, [0-9]ale zamiast tego zawiera alternatywne skrypty.
dolmen,

Wygląda to trochę dziwnie, że -0 jest prawidłową liczbą, ale RFC 4627 na to pozwala i twoje wyrażenie regularne jest z nim zgodne.
ceving

1

Końcowy przecinek w tablicy JSON spowodował zawieszenie się mojego Perla 5.16, prawdopodobnie dlatego, że ciągle się cofał. Musiałem dodać dyrektywę kończącą wycofywanie:

(?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) )(*PRUNE) \s* )
                                                                                   ^^^^^^^^

W ten sposób, gdy zidentyfikuje konstrukcję, która nie jest „opcjonalna” ( *lub ?), nie powinna próbować cofać się do niej w celu zidentyfikowania jej jako czegoś innego.


0

Jak napisano powyżej, jeśli używany język ma dołączoną bibliotekę JSON, użyj jej, aby spróbować zdekodować ciąg i złapać wyjątek / błąd, jeśli się nie powiedzie! Jeśli język nie (właśnie miał taki przypadek z FreeMarker), następujące wyrażenie regularne mogłoby przynajmniej zapewnić bardzo podstawową walidację (zostało napisane dla PHP / PCRE, aby było testowalne / użyteczne dla większej liczby użytkowników). Nie jest tak niezawodne jak przyjęte rozwiązanie, ale też nie jest tak straszne =):

~^\{\s*\".*\}$|^\[\n?\{\s*\".*\}\n?\]$~s

krótkie wyjaśnienie:

// 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)

jeśli przegapiłem coś, co mogłoby to nieumyślnie zepsuć, jestem wdzięczny za komentarze!


0

Regex, który weryfikuje prosty JSON, a nie JSONArray

sprawdza klucz (ciąg): wartość (ciąg, liczba całkowita, [{klucz: wartość}, {klucz: wartość}], {klucz: wartość})

^\{(\s|\n\s)*(("\w*"):(\s)*("\w*"|\d*|(\{(\s|\n\s)*(("\w*"):(\s)*("\w*(,\w+)*"|\d{1,}|\[(\s|\n\s)*(\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})){1}(\s|\n\s)*(,(\s|\n\s)*\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})?)*(\s|\n\s)*\]))((,(\s|\n\s)*"\w*"):(\s)*("\w*(,\w+)*"|\d{1,}|\[(\s|\n\s)*(\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})){1}(\s|\n\s)*(,(\s|\n\s)*\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):("\w*"|\d{1,}))*(\s|\n)*\})?)*(\s|\n\s)*\]))*(\s|\n\s)*\}){1}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d*|(\{(\s|\n\s)*(("\w*"):(\s)*("\w*(,\w+)*"|\d{1,}|\[(\s|\n\s)*(\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})){1}(\s|\n\s)*(,(\s|\n\s)*\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})?)*(\s|\n\s)*\]))((,(\s|\n\s)*"\w*"):(\s)*("\w*(,\w+)*"|\d{1,}|\[(\s|\n\s)*(\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):(\s)*("\w*"|\d{1,}))*(\s|\n)*\})){1}(\s|\n\s)*(,(\s|\n\s)*\{(\s|\n\s)*(("\w*"):(\s)*(("\w*"|\d{1,}))((,(\s|\n\s)*"\w*"):("\w*"|\d{1,}))*(\s|\n)*\})?)*(\s|\n\s)*\]))*(\s|\n\s)*\}){1}))*(\s|\n)*\}$

przykładowe dane, które są weryfikowane przez ten kod JSON

{
"key":"string",
"key": 56,
"key":{
        "attr":"integer",
        "attr": 12
        },
"key":{
        "key":[
            {
                "attr": 4,
                "attr": "string"
            }
        ]
     }
}


-3

Zdaję sobie sprawę, że to sprzed ponad 6 lat. Myślę jednak, że istnieje rozwiązanie, o którym nikt tutaj nie wspomniał, a które jest o wiele łatwiejsze niż regexing

function isAJSON(string) {
    try {
        JSON.parse(string)  
    } catch(e) {
        if(e instanceof SyntaxError) return false;
    };  
    return true;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.