Bina ungkapan biasa untuk menambah petikan berganda pada bahagian nilai JSON yang tidak mempunyai petikan berganda
P粉231112437
P粉231112437 2023-08-17 19:06:54
0
1
561
<p>Saya mempunyai banyak rentetan JSON yang cacat, seperti ini: </p> <pre class="brush:php;toolbar:false;">{ "id":23424938, "nama":aN, "ref":aN, "jul":aN, "kucing":{}, "src":[], "Kod":"SA", "jenis":d, "spesifikasi":[i,j], "kanak-kanak":a }</pre> <p>Saya cuba membina regex untuk menggandakan petikan nilai JSON tanpa kejayaan. </p> <p>Saya akhirnya menggunakan <kod>/":([^"d{[]+?[^,}]?)/</code> seperti <kod>[i,j]</kod>, ia tidak akan ditukar kepada <kod>["i","j"]</code>. </p> <p>Bolehkah anda membantu saya dengan nilai dalam kurungan? </p> <p>https://regex101.com/r/CGskmy/1</p>
P粉231112437
P粉231112437

membalas semua(1)
P粉755863750

Tugas ini akan menjadi agak sukar kerana kekaburan. Contohnya, { "x": [y] } 是变成 { "x": "[y]" } 还是变成 { "x": ["y"] }?我会假设未加引号的字符串不包含 JSON 控制字符,例如 '[', ']', '{', '}', '"', ':', ','.

Saya rasa anda boleh mencapai ini menggunakan kumpulan penangkapan bernama, yang merupakan ciri dalam PHP yang mungkin menggunakan PCRE. Ini memerlukan beberapa pengaturcaraan untuk melaksanakan penggantian. Operasi preg_replace biasa tidak mencukupi kerana kami tidak menggantikan semua perlawanan.

Ini adalah kaedah yang saya hasilkan. Mula-mula, saya memadankan rentetan yang dipetik dan mengabaikannya. Kedua, saya memadankan nombor dan mengabaikannya. Akhirnya, saya memadankan rentetan yang tidak disebut dan menyimpannya dalam kumpulan penangkap yang dipanggil "tidak disebut". Ambil perhatian bahawa PCRE akan cuba memadankan alternatif ini dalam susunan yang dipadankan. Rentetan tanpa petikan dipadankan hanya jika rentetan dan nombor yang dipetik tidak boleh dipadankan. Ini adalah kunci kepada pendekatan ini.

Setelah saya memadankan semua rentetan yang tidak disebut, ia hanya perlu menggabungkan rentetan keluaran dengan penggantian. Ini dilakukan dengan mengulangi padanan dan menyalin serpihan rentetan ke dalam output.

<?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;

Saya tidak berurusan dengan sintaks nombor JSON penuh, mahupun sintaks JSON seperti truefalsenull. Semoga jawapan ini adalah titik permulaan dan anda boleh mengubahnya mengikut keperluan anda.

InSync menyediakan ungkapan biasa yang bagus yang tidak menggunakan kumpulan penangkap bernama tetapi sebaliknya mengarahkan PCRE untuk melangkau perlawanan yang tidak diingini.

(?:
  "(?:[^\"rrreee-\x1F\x7F]|\["\/bfnrt]|\u[\dA-Fa-f]{4})*"
|
  -?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?
)
(*SKIP)(*FAIL)
|
[^{}[\]:,\s]+
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan