Javascriptでkeys
文字列から個々のJSON
を検索して、Value
をRegex
で返すことができるかどうかを確認しようとしています。 JSON
検索ツールを構築するようなものです。
次のJSONを想像してください
"{
"Name": "Humpty",
"Age": "18",
"Siblings" : ["Dracula", "Snow White", "Merlin"],
"Posts": [
{
"Title": "How I fell",
"Comments": [
{
"User":"Fairy God Mother",
"Comment": "Ha, can't say I didn't see it coming"
}
]
}
]
}"
JSON
文字列を検索して、個々のプロパティのみを取得できるようにしたいのですが。
すでにfunction
であると想定すると、次のようになります。
function getPropFromJSON(prop, JSONString){
// Obviously this regex will only match Keys that have
// String Values.
var exp = new RegExp("\""+prop+"\"\:[^\,\}]*");
return JSONString.match(exp)[0].replace("\""+prop+"\":","");
}
Value
のKey
のサブストリングを返します。
例えば.
getPropFromJSON("Comments")
> "[
{
"User":"Fairy God Mother",
"Comment": "Ha, can't say I didn't see it coming"
}
]"
JSON.parse()
を使用する代わりになぜこれを実行するのか疑問に思われる場合は、localStorage
の周りにJSONドキュメントストアを構築しています。 localStorage
はキーと値のペアのみをサポートするため、JSON
全体のDocument
文字列を一意のKey
に格納します。ドキュメントでクエリを実行できるようにしたいのですが、理想的には、Collection
のDocuments
全体のJSON.parsing()
のオーバーヘッドなしに、Keys
/nested Keys
を再帰的に検索して一致を見つけます。
私はregex
が得意ではないので、これを行う方法がわからないか、またはregex
だけでも可能かどうかはわかりません。これは、それが可能かどうかを確認するための実験にすぎません。解決策として他のアイデアがあれば幸いです。
私はあなたがこれをすることを強くお勧めしません。ここで明確に述べられているように、JSONは通常の言語ではありません: https://cstheory.stackexchange.com/questions/3987/is-json-a-regular-language
上記の投稿から引用するには:
たとえば、配列の配列の配列を考えます。
[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ]
明らかに、それを真の正規表現で解析することはできません。
JSONをオブジェクト(JSON.parse)に変換し、構造を走査するための検索機能を実装することをお勧めします。
それ以外に、ダグラス・クロックフォードの json2.js 解析メソッドの要点を見ることができます。おそらく、変更されたバージョンでは、JSON文字列を検索して、構造全体をオブジェクトに変換せずに、探していた特定のオブジェクトを返すことができます。これは、JSONから他のデータを取得しない場合にのみ役立ちます。もしそうなら、あなたも最初から全部を変えたかもしれません。
[〜#〜]編集[〜#〜]
正規表現がどのように機能しないかをさらに示すために、JSONを解析しようとする正規表現を次に示します
それを http://regexpal.com/ にプラグインすると、「Dot Matches All」がチェックされます。あなたはそれがいくつかの要素にうまくマッチできることがわかります:
正規表現
"Comments"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON一致
"Comments": [ { "User":"Fairy God Mother", "Comment": "Ha, can't say I didn't see it coming" } ]
正規表現
"Name"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON一致
"Name": "Humpty"
ただし、ネストされた配列を持つ「Posts」などのより高い構造のクエリを開始するとすぐに、「]」が指定された終わりであるというコンテキストが正規表現にないため、構造を正しく返すことができないことがわかります。構造。
正規表現
"Posts"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON一致
"Posts": [ { "Title": "How I fell", "Comments": [ { "User":"Fairy God Mother", "Comment": "Ha, can't say I didn't see it coming" } ]
まず、JSONオブジェクトを文字列化します。次に、一致した部分文字列の開始と長さを格納する必要があります。例えば:
"matched".search("ch") // yields 3
JSON文字列の場合、これはまったく同じように機能します(カンマと中かっこを明示的に検索している場合を除く)。この場合、正規表現を実行する前に、JSONオブジェクトを事前に変換することをお勧めします(例::、{、})。
次に、JSONオブジェクトを再構築する必要があります。私が作成したアルゴリズムは、一致インデックスから逆方向に再帰的に戻ることでJSON構文を検出することでこれを行います。たとえば、疑似コードは次のようになります。
find the next key preceding the match index, call this theKey
then find the number of all occurrences of this key preceding theKey, call this theNumber
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
return this object called parentChain
この情報を使用すると、正規表現を使用してJSONオブジェクトをフィルタリングし、キー、値、および親オブジェクトチェーンを返すことができます。
私が作成したライブラリとコードは http://json.spiritway.co/ で確認できます。