JSON上的正则表达式替换是从数组中删除对象

时间:2014-11-05 23:45:01

标签: javascript regex

我试图提高对正则表达式的理解,但这个让我很神秘。 我开始时将一些文字定义为:

var txt = "{\"columns\":[{\"text\":\"A\",\"value\":80},{\"text\":\"B\",\"renderer\":\"gbpFormat\",\"value\":80},{\"text\":\"C\",\"value\":80}]}";

并按如下方式进行替换:

txt.replace(/\"renderer\"\:(.*)(?:,)/g,"\"renderer\"\:gbpFormat\,");

导致:

"{"columns":[{"text":"A","value":80},{"text":"B","renderer":gbpFormat,"value":80}]}"

我期望renderer属性值删除它的引号;已经发生过,但C列完全没有了!我真的很想有人解释我的正则表达式如何删除列C

作为额外的奖励,如果您可以解释如何删除renderer的任何值周围的引号(即我不必在正则表达式中对值gbpFormat进行硬编码)&#39 ;太棒了。

3 个答案:

答案 0 :(得分:2)

当您需要懒惰操作符时,您正在使用贪心操作符。改变这个:

"renderer":(.*)(?:,)
              ^---- add here the '?' to make it lazy

"renderer":(.*?)(?:,)

<强> Working demo

enter image description here

您的代码应为:

txt.replace(/\"renderer\"\:(.*?)(?:,)/g,"\"renderer\"\:gbpFormat\,");

如果您正在学习正则表达式,请查看此documentation以了解有关贪婪的更多信息。理解这一点的一个很好的提取是:

  

注意贪婪

     

假设您要使用正则表达式来匹配HTML标记。你知道的   输入将是一个有效的HTML文件,因此正则表达式会这样做   不需要排除使用尖括号的任何无效使用。如果它坐   在尖括号之间,它是一个HTML标记。

     

大多数正常表达新手会尝试使用&lt;。+&gt;。他们   当他们在像这样的字符串上测试它时会感到惊讶   第一次测试。您可能希望正则表达式匹配和何时   在那场比赛后继续,

     

但事实并非如此。正则表达式将匹配第一个。显然不是   我们想要什么。原因是加分是贪心的。那就是   加号使正则表达式引擎经常重复前面的标记   可能。只有当这会导致整个正则表达式失败时,才会出现正则表达式   发动机回溯。也就是说,它会回到加号,让它给   在最后一次迭代中,继续执行正则表达式的其余部分。

     

就像加号一样,明星和使用花括号的重复是   贪婪。

答案 1 :(得分:0)

试试这样:

txt = txt.replace(/"renderer":"(.*?)"/g,'"renderer":$1');

您使用的表达式中的问题是这一部分:

(.*)(?:,)

默认情况下,*量词默认为贪婪,这意味着它尽可能地吞噬,因此它会运行到字符串中的最后一个逗号。最简单的解决方案是将其转换为非贪婪量词,方法是在星号后添加一个问号,并将表达式的那一部分更改为这样

(.*?)(?:,)

对于我在本答案顶部提出的解决方案,我还删除了与逗号匹配的部分,因为我认为仅仅匹配引号之间的所有内容更容易。至于你的奖金问题,要替换匹配的值而不是硬编码gbpFormat,我使用了反向引用($1),它会将第一个匹配的组插入到替换字符串中。

答案 2 :(得分:0)

不要使用regexp操纵JSON。正如你所发现的那样,你很可能会破坏它,更重要的是你没有必要这样做。

此外,一旦你改变了

'{"columns": [..."renderer": "gbpFormat", ...]}'

'{"columns": [..."renderer": gbpFormat, ...]}'      // remove quotes from gbpFormat

然后这不再是有效的JSON 。 (JSON要求属性值为数字,引用的字符串,对象或数组。)因此,您将无法解析它,或将其发送到任何地方并正确解释它。

因此,您应该先解析它,然后操纵生成的实际JS对象:

var object = JSON.parse(txt);
object.columns.forEach(function(column) {
    column.renderer = ghpFormat;
});

如果您想用值本身替换renderer属性的任何引用值,那么您可以尝试

    column.renderer = window[column.renderer];

假设该值在全局命名空间中可用。

这个问题属于“我需要一个正则表达式,或者我写了一个并且它不起作用,我不确定为什么它必须是正则表达式,但我听说它们可以做各种各样的事情,这就是我想象中我必须要的。“人们使用regexp尝试进行太多复杂的匹配,拆分,扫描,替换和验证任务,包括复杂的语言,如HTML,或者在这种情况下使用JSON。几乎总有一种更好的方法。

我唯一能想象用regexp来操作JSON的时候是因为JSON在某种程度上被破坏了,可能是由于服务器代码中的一个错误,并且需要修复它以便可以解析。