【问题标题】:Is there a better way to 'doctor' JSON code? [closed]有没有更好的方法来“医生”JSON 代码? [关闭]
【发布时间】:2023-04-11 07:56:01
【问题描述】:

我下载了一些网页,其中包含嵌入到 javascript 中的 JSON 代码。我需要对其进行解码,但它是不正确 JSON,并且包含单引号和双引号,这会导致解码子程序出错。

注意:JSON 以块形式提取到字符串变量中,DATA 块代表某种形式的错误 JSON 代码(主要问题在于代表网站访问者客户端输入的部分),JSON 具有相当深度递归结构。

到目前为止,我找不到比附加的仍然不正确的波纹管代码更好的解决方案。

有没有更好的方法医生收到 JSON 代码? [可能在正则表达式中使用 (??{ code})]

use strict;
use warnings;
use diagnostics;

while( <DATA> ) {
    chomp;
    print "IN:  $_\n";
    s/"/'/g;
    print "OUT: $_\n" if s/'(.*?)'\s*:\s*'(.*?)'(,|\s*\})/"$1": "$2"$3/g;
}

__DATA__
{ "d1": "some data here", "d2":"some "data" here", "d3": "some "data" here "year"", "d4": { "x1": "some "data" here" } }
{ "d2": "some data here", "d2":"some "data" here", "d3": "some "data" here "year"" }
{ 'd3': 'some data here', "d2":"some "data" here", "d3": "some "data" here "year"" }
{ "d4": 'some data here', "d2":"some "data" here", "d3": "some "data" here "year"", "d4": { "x1": "some "data" here" } }
{ 'd5': "some data here", "d2":"some "data" here", "d3": "some "data" here "year"" }

输出

IN:  { "d1": "some data here", "d2":"some "data" here", "d3": "some "data" here "year"", "d4": { "x1": "some "data" here" } }
OUT: { "d1": "some data here", "d2": "some 'data' here", "d3": "some 'data' here 'year'", "d4': { 'x1": "some 'data' here" } }
IN:  { "d2": "some data here", "d2":"some "data" here", "d3": "some "data" here "year"" }
OUT: { "d2": "some data here", "d2": "some 'data' here", "d3": "some 'data' here 'year'" }
IN:  { 'd3': 'some data here', "d2":"some "data" here", "d3": "some "data" here "year"" }
OUT: { "d3": "some data here", "d2": "some 'data' here", "d3": "some 'data' here 'year'" }
IN:  { "d4": 'some data here', "d2":"some "data" here", "d3": "some "data" here "year"", "d4": { "x1": "some "data" here" } }
OUT: { "d4": "some data here", "d2": "some 'data' here", "d3": "some 'data' here 'year'", "d4': { 'x1": "some 'data' here" } }
IN:  { 'd5': "some data here", "d2":"some "data" here", "d3": "some "data" here "year"" }
OUT: { "d5": "some data here", "d2": "some 'data' here", "d3": "some 'data' here 'year'" }

【问题讨论】:

  • 如果您确定您所追求的数据(内容方面)不包含',那么简单地将所有单引号替换为双引号会更容易吗?或者,只需将 ' 替换为 ["]`,将其放入一个组中,然后使用它。
  • JSON 可能有很多包含,例如I'mname'sname"s"2019"they'veIt's... 没有一致性的地方应该是@ 987654333@ 用户输入" 例如I"m - 一些输入是西里尔语,例如{"title": "описание наименование фильма "новый 2019" сериал"}
  • 在一般情况下,不,没有办法预测哪些引号格式正确。如果键像您的示例所暗示的那样单调,那么简单的正则表达式应该能够达到可接受的准确性,尽管您可能仍希望执行手动审查。
  • this post(和 cmets)的第二部分查看一些想法/正则表达式来修复稍微无效的 JSON
  • 根据 OP 的 cmets,问题是错误的。 OP 实际上并没有遇到诸如在他们的问题中找到的数据,而是有效的 JavaScript。投票结束,直到这个问题得到解决。

标签: json regex perl double-quotes


【解决方案1】:

我不会为您损坏的 JSON 编写解析器。教授如何编写解析器超出了本网站的范围。此外,您可以轻松地基于现有的 JSON 解析器(例如 JSON::PP)。

我能做的是帮助您解决唯一困难的部分:确定引号是结束文字还是需要转义。例如,确定"some "data" here" 中的第二个和第三个引号不会结束文字,而第四个会结束。

事实证明,很容易做出可靠的猜测:向前看!如果引号后面跟着可选的空格 :,}] 在文字结束时有效,则引号可能合法地结束文字。否则,它是文字的一部分,需要转义。

【讨论】:

  • 注意:我尝试处理的 JSON 是由 YouTube 网站返回的。
  • 1) 您发布的不是 JSON。它甚至不是 JavaScript。 2) 我怀疑您发布的内容(例如"some "data" here")来自 Google。 3) 那又怎样?
  • Re "我没有看到你要求更多。",那你为什么提到数据是 161 KB 的大小?
  • Re "现在请看下面网页的源代码", 目的是什么? (我看到了有效的 JavaScript,与您发布的不同。)
  • 这与我的回答有什么关系?
【解决方案2】:

您似乎想要进行以下更正:

1) 将任何 json 字段名称从单引号更改为双引号。

2) 将任何 json 字符串字段值从单引号更改为双引号

3) 将 json 字符串字段中的任何嵌套双引号更改为双引号字符串内的单引号

4) 确保 json 字段名称后的冒号后至少有一个空格。

您能否在输出部分仔细检查示例 1 和 4 的结尾?当然,您不想将 json 字段名称更改为包含冒号、单引号和大括号。此外,如果您确实打算这样做,那么大括号现在在这些行上是不平衡的。

所有这些……正则表达式可能不是适合这项工作的工具。为此,您可能需要一个上下文相关的解析器(以跟踪所有嵌套级别)。

如果您对正在下载的页面有任何控制权,请让他们修复它。否则......你几乎必须能够处理任何事情,所以你需要上下文敏感的解析器 - 如果它变得太混乱,请准备好丢弃一些输入。 ...而不是崩溃或进入无限循环。

【讨论】:

  • 布伦达,你说得非常正确,应该做哪些更正才能使 JSON 可解析。但是我已经知道了,我的问题是是否可以用 regex 来纠正这种异常。问题是 JSON 具有 recursive 结构,而 regex 需要递归解析。通过查看regex 文档,我发现只有使用(??{ code }) 功能才有这种可能性。我采用了这种方法,但是幸运地理解了它的工作原理并没有让我达到预期的结果。
  • 我完全可以接受这样的回答 异常。否则,这个 JSON 只能通过编写处理所有可能情况的解析器来处理。我一直希望对 regex 更有经验的人可以澄清在类似情况下使用 (??{ code }) 功能。
  • JSON 虽然代表 JavaScript Object Notation,但 JavaScript 和 JSON 保持数据略有不同。 JavaScript 允许 { 'key': "value"},但 JSON 解析器需要 {"key":"value"}。这种问题很容易用 regex 纠正,因为 key 从来没有递归结构。 value 部分的情况完全不同,因为根据定义它可以包含 recursion。此刻我来到了其他产生预期结果的解决方案,它正处于测试阶段,看看是否有任何其他异常会出现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 2020-03-14
  • 1970-01-01
  • 2020-03-18
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
相关资源
最近更新 更多