我遇到一个问题,即有人在以后没有正确地转义值中的双引号被解释为JSON字符串。
字符串示例:
{"description":"This is my 12" pizza I ordered.","value":"1"}
当我尝试让JSON.parse()处理它时,由于未转义的双引号(参考以英寸为单位的大小),它会产生错误
起初,我想 - 只是这样做:
string.replace(/\"/g,'\"');
但当然这也逃脱了所有有效的双引号。所以,我不是正则表达式的专家,但我四处寻找答案,我认为这需要一个负面的预测?
有人可以帮助构建一个正则表达式来查找(替换)任何doublequote序列,其中违规doubleqoute之后的下一个2字符序列不是空格逗号吗?
我知道这不是一个完全普遍的解决方案,(让人们解决他们的问题),但不幸的是我没有普遍修复的奢侈。
TIA
更新 - 而不是考虑示例字符串(仅用于说明)。是否可以在每个双引号之前和之后测试是否存在有效的JSON - 即查找以下任何字符 ,{[:
每个双引号之前和之后?我想这就是我的要求 - 这可以通过前瞻/后面的正则表达式完成吗?
答案 0 :(得分:1)
这是我能做的最好的事情,利用JSON中未转义的报价只能出现在某些地方这一事实。
input = '{"description":"This is my 12" pizza, and I want "thin crust"","value":"1"}';
console.log(input);
output = input.replace(/{"/g, '_OPEN_').replace(/":"/g, '_COLON_').replace(/","/g, '_COMMA_').replace(/"}/g, '_CLOSE_');
output = output.replace(/"/g, '\\"');
output = output.replace(/_OPEN_/g, '{"').replace(/_COLON_/g, '":"').replace(/_COMMA_/g, '","').replace(/_CLOSE_/g, '"}');
console.log(output)
可生产
{"description":"This is my 12" pizza, and I want "thin crust"","value":"1"}
{"description":"This is my 12\" pizza, and I want \"thin crust\"","value":"1"}
你可以用不太可能在输入中出现的字符串替换'OPEN','CLOSE'等,如果你不介意正则表达式是神秘的话,甚至可以控制字符。但正如其他人所指出的那样,没有任何解决方案适用于所有情况。无论你做什么,描述文本中都会出现一个会让你搞砸的值,因为与正确生成的JSON不同,你试图解析的语法是不明确的。
答案 1 :(得分:0)
一种方法:重建json字符串:
var str = '{"description":"This is my 12" pizza I ordered.","value":"1"}';
var regex = /"(.*?)"(?=\s*([,:])\s*"|(}))/g;
var result = '{';
var arr = regex.exec(str);
while (arr != null) {
result += '"' + arr[1].replace(/\\?"/g, '\\"') + '"';
if (arr[2]) result += arr[2];
if (arr[3]) result += arr[3];
arr = regex.exec(str);
}
console.log(result);
答案 2 :(得分:0)
不是一个单行的正则表达式,但我认为这样做更安全:
json_string = '{"description":"This is my 12" pizza: which can also contain other "," which would break in a one liner regex.","value":"1"}';
console.log(json_string);
// save the value for later use
var value = json_string.match(/"value":"(.+)"}$/)[1];
// isolate just the description value..
// remove the ","value... from the end
var desc = json_string.replace(/","value":".+"}$/, '');
// remove the opening {"description":" from the description value
desc = desc.replace(/^{"description":"/, '');
// any remaining " in the description are unwanted to replace them
desc = desc.replace(/"/g, '"');
console.log(desc);
// now put it all back together - if you wanted too - but really you already have the description and value parsed out of the string
json_string = '{"description":"'+desc+'","value":"'+value+'"}'
console.log(json_string);
控制台输出如下:
{"description":"This is my 12" pizza: which can also contain other "," which would break in a one liner regex.","value":"1"}
This is my 12" pizza: which can also contain other "," which would break in a one liner regex.
{"description":"This is my 12" pizza: which can also contain other "," which would break in a one liner regex.","value":"1"}
注意如果描述中还包含您可能在正则表达式中使用的任何模式,则此方法不会中断
答案 3 :(得分:0)
尝试此替换:
repl = str.replace(/"(?= )/g, "\\\"");
答案 4 :(得分:0)
我讨厌回答我自己的问题,正如你们中的许多人所指出的那样,正确地说,由于一个流浪的,未逃避的双引号字符注入了歧义,事后完全无法修复坏JSON。可能这应该是一个正确的答案,不幸的是它不会解决我的问题。
对于那些遇到同样问题的人 - 我希望下面的功能可以帮助创可贴,直到你可以修复错误的JSON来源。基本上你必须查看每个双引号,然后在两个字符后面提前查看(至少)并根据前一个/下一个字符进行评估,看它是否可能在JSON中有效使用doubleqoute或无效。如果它无效,则拼接一个转义字符。下面的函数做得很好,虽然根据双引号引起的JSON畸形程度,你可能需要稍微扩展一下这个函数。我的希望是,对于那些在我的情况下,这至少提供了一个很好的起点。
感谢所有贡献 - 潜在解决方案的数量和广度非常棒,非常棒!
// fix unescaped double quotes / malformed JSON
function cleanseJSON(jsonStr)
{
for(var k=0;k<jsonStr.length;k++)
{
if(jsonStr.charAt(k)=='"')
{
var prevChar=jsonStr.charAt(k-1);
var prevChar2=jsonStr.charAt(k-2);
var nextChar=jsonStr.charAt(k+1);
var nextChar2=jsonStr.charAt(k+2);
var esc="\\";
var isValid=false;
var prevFix=false;
var postFix=false;
switch(prevChar)
{
case ':':
case '{':
case ',':
case '[':
case '\\': // already escaped
isValid=true;
break;
default:
prevFix=true;
}
switch(nextChar)
{
case ':':
case '}':
case ',':
if(nextChar2==' '){ // if there is a comma, but the next is a space consider it invalid JSON
break;
}
case ']':
case '\\': // already escaped
isValid=true;
break;
default:
postFix=true;
}
// first test to ensure the quote is likely bogus
if(!isValid)
{
if(prevFix){
jsonStr = [jsonStr.slice(0, k), esc, jsonStr.slice(k)].join('');
} else {
if(postFix){
jsonStr = [jsonStr.slice(0, k+1), esc, jsonStr.slice(k+1)].join('');
}
}
} // if not valid "
} // if we find a doublequote
} // for each char in the jsonStr
return jsonStr;
}