2016-09-26 9 views
2

ユーザーがJSONを提供するCLIアプリケーションがあります。 JSONが有効かどうかを確認する必要があります。JSON LIKE文字列が有効かどうかを確認します。 - JS regex

function isJsonValid(str) { 
    try { 
     JSON.parse(str); 
    } catch (e) { 
     return false; 
    } 
    return true; 
} 

しかし、私は私のアプリをデバッグしながら、私は、コマンドからのすべての"'spacesが取り除かれていることを少し問題があることに気づいた。私はこのようなsomehtingは素晴らしい仕事も見つけ 。ようにJSON :私は、これはJSONが何とか有効で取り除かかどうかをチェックします正規表現を必要とする

{key1:value1,key2:value2} 

{ 
    "key1": "value1", 
    "key2": "value2" 
} 

は、次のようなものに変更されます。

だから、のように見えるがすべき結果:

re.test({key1:value1,key2:value2}) // true 
re.test({key1:value1}) // true 
re.test({key1:value1,}) // false, extra comma 
re.test({key1:value1, key2}) // false, missing value of key2 
re.test({key1:value1, key2:value2) // false, missing closing } 
re.test({key1:value1, key2:value2}}) // false, extra closing } 

誰かが正規表現の部分で私を助けてくださいことはできますか?残念ながら、これは私の強い側面ではありません。

+2

をJSONはもはやJSONですが、それはあなたの入力されているとして、あなたがそれを検証したい場合は、あなただけ行う「取り除きません」トップレベルの 'key:value'ペアのみで示された単純なケースをテストする必要がありますか、またはネストされたオブジェクトや配列を許可する必要がありますか? – nnnnnn

+0

うん、入れ子配列はありません。したがって、JSONが次のようになっているかどうかテストする必要があります: '{' - 開き括弧、 'key' +': '+' value' +閉じ括弧 '}' 'key:value'部分は複数回繰り返すことができ、カンマで – Andurit

+0

???私はここで何か重要なものを逃しています関数が 'true'を返す場合、渡されたJSONは有効で、' false'を返すとエラーが発生し、JSONは無効です。なぜ再確認するのが気になるのですか? – Teemu

答えて

3

私が上記のコメントで述べたように、「取り除かれた」JSONはもちろんJSONではありません。ネストされたオブジェクトや配列について心配する必要はないことを確認しました。中括弧で囲まれたのペアの単純なリストだけです。

ので、次の正規表現は、各キーと値が[A-Za-z0-9_]と等価である正規表現\wを使用して「単語」の文字で構成されることを前提としています

var re = /^\{\w+:\w+(,\w+:\w+)*\}$/; 

明らかにあなたはどの文字変化するようにしたい場合キー名と値として使用できる場合は、\wをそれぞれ[A-Za-z0-9_]に置き換え、必要に応じて許可された文字を追加または削除するだけです。

EDIT:上記のコメントで、キーの名前と値に.を許可してください。

var re = /^\{[A-Z0-9._]+:[A-Z0-9._]+(,[A-Z0-9._]+:[A-Z0-9._]+)*\}$/i; 

しかし、あなたはおそらく、作品の全ての間にオプションのホワイトスペースを可能にしたいので、私はすべてのトークンの間\s*を追加することをお勧めしたい:だから、正規表現で大文字と小文字を区別しないiフラグを使用して

var re = /^\s*\{\s*[A-Z0-9._]+\s*:\s*[A-Z0-9._]+\s*(,\s*[A-Z0-9._]+\s*:\s*[A-Z0-9._]+\s*)*\}\s*$/i; 
 

 
console.log(re.test('{key1:value1,key2:value2}')) // true 
 
console.log(re.test('{key1:value1}'))    // true 
 
console.log(re.test(' { key1 : value1 , key2 : value2 , k3 : v3 } ')) // true 
 
console.log(re.test(' { k.j.m : v.a2 , k2.a.b : v.32 , k3 : v3 } ')) // true 
 
console.log(re.test('{key1:value1,}'))    // false, extra comma 
 
console.log(re.test('{key1:value1, key2}'))   // false, missing value of key2 
 
console.log(re.test('{key1:value1, key2:value2')) // false, missing closing } 
 
console.log(re.test('{key1:value1, key2:value2}}')) // false, extra closing }

は(私は名前で.を可能にするには、編集ビットがで複数の.文字を許可することに注意してください元の投稿には言及されていないより多くの要件が追加されているので、自分の答えを更新するために戻って来たいとは思っていません。厳密に1つの.を連続して保持し、先行または後続のドットがない場合は、上の正規表現がコンマを作成するために使用したのと同じ原則を適用します。)

+0

ちょっと@nnnnnnは値を考慮することができますかキーは単純な文字列ではなく、例えば'is.my.value'(その間にドットが追加されています) – Andurit

+0

はい、私はそれを私の答えで取り上げました:それぞれの\ wを大括弧で囲まれた文字のリストに置き換えてください。 – nnnnnn

2

ここでは、正規表現があります。

^{(([a-zA-Z0-9]+:[a-zA-Z0-9]+)(,[a-zA-Z0-9]+:[a-zA-Z0-9]+)*)?}$ 

Check your Examples here at Regex101.com

+0

親指アップ、素敵な答えに感謝します。もう少し複雑で、彼が最初だったので、nnnnが正しいとマークしました。しかし、たくさんありがとうございます。 – Andurit

+0

私は助けてくれると嬉しいです!マークされているかマークされていない、最高のソリューションが得られてうれしいです。 –

関連する問題