繁体   English   中英

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

[英]regex replace on JSON is removing an Object from Array

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

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)这太棒了。

您使用的是贪婪的运营商,而你需要一个懒惰的一个。 改变这个:

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

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

工作演示

在此输入图像描述

你的代码应该是:

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

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

留意贪婪

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

大多数刚接触正则表达式的人都会尝试使用<。+>。 当他们在像这是第一次测试的字符串上测试时,他们会感到惊讶。 您可能希望正则表达式匹配, 并在该匹配后继续,

但事实并非如此。 正则表达式将首先匹配。 显然不是我们想要的。 原因是加分是贪心的。 也就是说,加号使正则表达式引擎尽可能频繁地重复前面的标记。 只有这会导致整个正则表达式失败,正则表达式引擎才会回溯。 也就是说,它将返回到加号,让它放弃最后一次迭代,然后继续使用正则表达式的其余部分。

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

试试这样:

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

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

(.*)(?:,)

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

(.*?)(?:,)

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

不要使用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是否因某种方式被破坏,可能是由于服务器代码中的一个错误,并且需要修复它以便可以解析。

暂无
暂无

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

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