用于解析单个键的正则表达式:Javascript 中 JSON 中的值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8750127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:20:25  来源:igfitidea点击:

Regex for parsing single key: values out of JSON in Javascript

javascriptregexjson

提问by AshHeskes

I'm trying to see if it's possible to lookup individual keysout of a JSONstring in Javascript and return it's Valuewith Regex. Sort of like building a JSONsearch tool.

我想看看是否有可能查找个人keys一出JSON字符串中的Javascript并返回它ValueRegex。有点像构建JSON搜索工具。

Imagine the following 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"
                }
            ]
        }
    ]
}"

I want to be able to search through the JSONstring and only pull out individual properties.

我希望能够搜索JSON字符串并只提取单个属性。

lets assume it's a functionalready, it would look something like.

让我们假设它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+"\":","");    
}

It would return the substring of the Valuefor the Key.

它将返回Valuefor 的子字符串Key

e.g.

例如

getPropFromJSON("Comments")

> "[
    { 
        "User":"Fairy God Mother",
        "Comment": "Ha, can't say I didn't see it coming"
    }
]"

If your wondering why I want to do this instead of using JSON.parse(), I'm building a JSON document store around localStorage. localStorageonly supports key/value pairs, so I'm storing a JSONstring of the entire Documentin a unique Key. I want to be able to run a query on the documents, ideally without the overhead of JSON.parsing()the entire Collectionof Documentsthen recursing over the Keys/nested Keysto find a match.

如果您想知道为什么我要这样做而不是使用JSON.parse(),我正在围绕localStorage. localStorage仅支持键/值对,因此我JSON将整个字符串存储Document在一个唯一的Key. 我希望能够在其上运行的文件的查询,没有理想的开销JSON.parsing()全部CollectionDocuments然后迭代在Keys/嵌套Keys找到匹配。

I'm not the best at regexso I don't know how to do this, or if it's even possible with regexalone. This is only an experiment to find out if it's possible. Any other ideas as a solution would be appreciated.

我不是最擅长的,regex所以我不知道如何做到这一点,或者是否可以regex单独使用。这只是一个实验,以确定是否可能。任何其他想法作为解决方案将不胜感激。

回答by Brandon Boone

I would strongly discourage you from doing this. JSON is not a regular language as clearly stated here: https://cstheory.stackexchange.com/questions/3987/is-json-a-regular-language

我强烈建议您不要这样做。JSON 不是此处明确说明的常规语言:https: //cstheory.stackexchange.com/questions/3987/is-json-a-regular-language

To quote from the above post:

引用上面的帖子:

For example, consider an array of arrays of arrays:

[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ] 

Clearly you couldn't parse that with true regular expressions.

例如,考虑一个数组数组:

[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ] 

显然,您无法使用真正的正则表达式解析它。

I'd recommend converting your JSON to an object (JSON.parse) & implementing a find function to traverse the structure.

我建议将您的 JSON 转换为一个对象 (JSON.parse) 并实现一个 find 函数来遍历结构。

Other than that, you can take a look at guts of Douglas Crockford's json2.jsparse method. Perhaps an altered version would allow you to search through the JSON string & just return the particular object you were looking for without converting the entire structure to an object. This is only useful if you never retrieve any other data from your JSON. If you do, you might as well have converted the whole thing to begin with.

除此之外,您可以看看 Douglas Crockford 的json2.js解析方法的内容。也许更改后的版本将允许您搜索 JSON 字符串并只返回您要查找的特定对象,而无需将整个结构转换为对象。这仅在您从未从 JSON 中检索任何其他数据时才有用。如果你这样做了,你不妨从一开始就改变整个事情。

EDIT

编辑

Just to further show how Regex breaks down, here's a regex that attempts to parse JSON

只是为了进一步展示 Regex 如何分解,这是一个试图解析 JSON 的正则表达式

If you plug it into http://regexpal.com/with "Dot Matches All" checked. You'll find that it can match some elements nicely like:

如果您将其插入http://regexpal.com/并选中“Dot Matches All”。你会发现它可以很好地匹配一些元素,比如:

Regex

"Comments"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\") 

JSON Matched

"Comments": [
                { 
                    "User":"Fairy God Mother",
                    "Comment": "Ha, can't say I didn't see it coming"
                }
            ]

Regex

"Name"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")

JSON Matched

"Name": "Humpty"

正则表达式

"Comments"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\") 

JSON 匹配

"Comments": [
                { 
                    "User":"Fairy God Mother",
                    "Comment": "Ha, can't say I didn't see it coming"
                }
            ]

正则表达式

"Name"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")

JSON 匹配

"Name": "Humpty"

However as soon as you start querying for the higher structures like "Posts", which has nested arrays, you'll find that you cannot correctly return the structure since the regex does not have context of which "]" is the designated end of the structure.

但是,一旦您开始查询具有嵌套数组的“Posts”等高级结构,您就会发现无法正确返回该结构,因为正则表达式没有“]”是指定结尾的上下文结构体。

Regex

"Posts"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")

JSON Matched

"Posts": [
  {
      "Title": "How I fell",
      "Comments": [
          { 
              "User":"Fairy God Mother",
              "Comment": "Ha, can't say I didn't see it coming"
          }
      ]

正则表达式

"Posts"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")

JSON 匹配

"Posts": [
  {
      "Title": "How I fell",
      "Comments": [
          { 
              "User":"Fairy God Mother",
              "Comment": "Ha, can't say I didn't see it coming"
          }
      ]

回答by mikewhit

First, stringify the JSON object. Then, you need to store the starts and lengths of the matched substrings. For example:

首先,将 JSON 对象字符串化。然后,您需要存储匹配子字符串的开头和长度。例如:

"matched".search("ch") // yields 3

For a JSON string, this works exactly the same (unless you are searching explicitly for commas and curly brackets in which case I'd recommend some prior transform of your JSON object before performing regex (i.e. think :, {, }).

对于 JSON 字符串,这完全相同(除非您明确搜索逗号和大括号,在这种情况下,我建议您在执行正则表达式之前先对 JSON 对象进行一些转换(即认为:、{、})。

Next, you need to reconstruct the JSON object. The algorithm I authored does this by detecting JSON syntax by recursively going backwards from the match index. For instance, the pseudo code might look as follows:

接下来,您需要重建 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

With this information, it is possible to use regex to filter a JSON object to return the key, the value, and the parent object chain.

有了这些信息,就可以使用正则表达式来过滤 JSON 对象以返回键、值和父对象链。

You can see the library and code I authored at http://json.spiritway.co/

您可以在http://json.spiritway.co/ 上查看我编写的库和代码