我试图提高对正则表达式的理解,但这个让我很神秘。 我开始时将一些文字定义为:
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 ;太棒了。
答案 0 :(得分:2)
当您需要懒惰操作符时,您正在使用贪心操作符。改变这个:
"renderer":(.*)(?:,)
^---- add here the '?' to make it lazy
要
"renderer":(.*?)(?:,)
<强> Working demo 强>
您的代码应为:
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在某种程度上被破坏了,可能是由于服务器代码中的一个错误,并且需要修复它以便可以解析。