Erstellen Sie einen regulären Ausdruck, um Teilen eines JSON-Werts, die keine doppelten Anführungszeichen enthalten, doppelte Anführungszeichen hinzuzufügen
P粉231112437
P粉231112437 2023-08-17 19:06:54
0
1
511
<p>Ich habe viele fehlerhafte JSON-Strings, wie zum Beispiel diesen: </p> <pre class="brush:php;toolbar:false;">{ "id":23424938, "name":aN, "ref":aN, "jul":aN, "Katze":{}, "src":[], „Code“: „SA“, "Typ":d, "spec":[i,j], „Kind“:a }</pre> <p>Ich versuche erfolglos, einen regulären Ausdruck zu erstellen, um einen JSON-Wert in doppelte Anführungszeichen zu setzen. </p> <p>Am Ende habe ich <code>/":([^"d{[]+?[^,}]?)/</code> verwendet, was alles außer den Werten innerhalb des Arrays korrigiert hat. B. <code>[i,j]</code>, wird es nicht in <code>["i",j"]</code> konvertiert. </p> <p>Können Sie mir mit den Werten in Klammern helfen? </p> <p>https://regex101.com/r/CGskmy/1</p>
P粉231112437
P粉231112437

Antworte allen(1)
P粉755863750

这个任务会有一些困难,因为存在歧义。例如,{ "x": [y] } 是变成 { "x": "[y]" } 还是变成 { "x": ["y"] }?我会假设未加引号的字符串不包含 JSON 控制字符,例如 '[', ']', '{', '}', '"', ':', ','

我认为你可以使用命名捕获组来完成这个任务,这是 PHP 中的一个功能,使用 PCRE 可以实现。这需要一些编程来执行替换。通常的 preg_replace 操作是不够的,因为我们不会替换所有匹配项。

这是我想出来的方法。首先,我匹配引号字符串并忽略它们。其次,我匹配数字并忽略它们。最后,我匹配未加引号的字符串并将其存储在名为“unquoted”的捕获组中。请注意,PCRE 将按照这些替代项的顺序尝试匹配。只有在无法匹配引号字符串和数字时,才会匹配未加引号的字符串。这是这种方法的关键。

一旦我匹配到所有未加引号的字符串,就只需要将输出字符串与替换一起拼接起来。这是通过迭代匹配项并将字符串片段复制到输出中来完成的。

<?php

$in = <<<'IN'
{
    "id":23424938,
    "name":aN,
    "ref":aN,
    "jul":aN,
    "cat":{},
    "src":[],
    "Code":"SA",
    "type":d,
    "spec":[i,j],
    "child":a
}
IN;

// 在输入字符串上匹配。我们特别关注“unquoted”匹配组。
$pattern = '/(?:"(?:\\\\"|[^"])+")|(?:[\d.]+)|(?P<unquoted>[^{}\[\]":,\s][^{}\[\]":,]*(?<!\s))/';
preg_match_all($pattern, $in, $matches, PREG_UNMATCHED_AS_NULL | PREG_OFFSET_CAPTURE);

// 输出字符串
$out = '';

// 跟踪输入字符串的当前索引
$ix = 0;

// 循环遍历所有未加引号的匹配项
foreach ($matches['unquoted'] as $match) {
    $str = $match[0];
    $pos = $match[1];
    if ($str !== NULL) {
        // 将输入字符串复制到输出字符串
        $out .= substr($in, $ix, $pos - $ix);
        // 将匹配的字符串复制到输出字符串,用引号括起来
        $out .= '"' . $str . '"';
        // 更新输入字符串索引
        $ix = $pos + strlen($str);
    }
}

// 将输入字符串的尾部复制到输出字符串
$out .= substr($in, $ix, strlen($in) - $ix);

// 输出字符串
echo $out;

我没有处理完整的 JSON 数字语法,也没有处理 JSON 语法,例如 truefalsenull。希望这个答案是一个起点,你可以根据自己的需求进行调整。

InSync 提供了一个很好的正则表达式,它不使用命名捕获组,而是命令 PCRE 跳过不需要的匹配项。

(?:
  "(?:[^\\"\0-\x1F\x7F]|\\["\\/bfnrt]|\\u[\dA-Fa-f]{4})*"
|
  -?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?
)
(*SKIP)(*FAIL)
|
[^{}[\]:,\s]+
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage