繁体   English   中英

javascript regex替换字符串中的所有双引号,除非双引号后跟空格或逗号

[英]javascript regex replace all doublequotes in string unless the doublequote is followed by space or comma space

我有一个问题,就是有人以后没有正确地转义值中的双引号以解释为JSON字符串。

字符串示例:

{"description":"This is my 12" pizza I ordered.","value":"1"}

当我尝试让JSON.parse()处理时,由于未转义的双引号(指的是以英寸为单位的大小),因此会出现错误

刚开始,我想-要做:

string.replace(/\"/g,'\"');

但是当然,这也会转义所有有效的双引号。 因此,我不是正则表达式方面的专家,但是我环顾四周寻找答案,我认为这需要否定的前瞻性吗?

有人可以帮忙构造一个正则表达式来查找(替换)任何双引号序列,其中有问题的doubleqoute之后的下一个2个字符序列不是空格吗?

我知道这不是一个全面的修补程序(要让这个人最终解决这个问题),但是不幸的是,我没有通用的修补程序。

TIA

更新-不考虑示例字符串(仅用于说明)。 是否可以在每个双引号前后测试有效JSON的存在-即查找以下任何字符,{[:

每个双引号之前和之后? 我想这就是我要问的-可以在正则表达式后面进行预行吗?

这是我能做的最好的事情,利用了一个事实,即在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不同,您尝试解析的语法是模棱两可的。

一种方法:重建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);

不是一个线性正则表达式,但是我认为这样更安全:

 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"}

注意:如果说明中还包含您可能在正则表达式一个内衬中使用的任何模式,则此方法不会中断

试试这个替换:

repl = str.replace(/"(?= )/g, "\\\"");

我讨厌回答我自己的问题,正如你们中的许多人所指出的那样,正确地解决了不良的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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM