【问题标题】:Regex alteration with shared sub expression with different prefix and suffix expressions具有不同前缀和后缀表达式的共享子表达式的正则表达式更改
【发布时间】:2026-01-24 00:00:01
【问题描述】:

我有下面的正则表达式,它有 3 个交替(请参阅下面的整个正则表达式),每个都有自己的前缀和后缀字符。我觉得这重复得太多了,如果可能的话,我想简化一下。我正在匹配格式不正确的 JSON 字符串中的值,以用索引键替换没有键的值。

每个替换都应匹配前缀和后缀对与子表达式。我现在有 3 双,但这可能会改变。如果我有更多对,那么整个正则表达式将成为修改和理解我是否需要修改重复的子表达式的噩梦。

问题

如何缩短下面的整个正则表达式,而不需要为列出的后缀和前缀对重复子表达式

子表达式,每次交替重复

("(?:[^\\"]+|\\.)*")

前缀/后缀对

  1. { ,
  2. ,,,
  3. ,}

整个正则表达式

/\{("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=\})/g

测试字符串

  • {"trailer":"","pallet":"A","date":"11-Dec-15","c","z","a"}
  • {"trailer":"","pallet":"A","a","date":"11-Dec-15"}
  • {"a","trailer":"","pallet":"A","date":"11-Dec-15"}
  • {"a","trailer":"","pallet":"A","date":"11-Dec-15","z\""}
  • {"trailer":"","pallet":"A","11-Dec-15"}
  • {"trailer\"","pallet":"A","11-Dec\"-15","z\""}

Live Example

请限制对正则表达式替代而不是 JSON 验证技术的回答,因为我试图更好地理解正则表达式,这只是我使用的示例。

【问题讨论】:

  • 您可以使用带有RegExp 构造函数的动态正则表达式构建:将("(?:[^\\"]+|\\.)*") 声明为构建块变量,然后在模式中重用它。不过,您必须将所有反斜杠加倍。
  • 如果我没有理解错,您可以使用单个表达式来(多个)一次匹配所有部分,只需使用前瞻和前瞻资产。每个都使用多种替代方法来匹配每种情况下的任一有效分隔符。
  • @bitifet 我以前试过这个,但发现你不能在后视中使用表达式,所以我必须对每次出现进行硬编码。这仍然让我不得不指定我希望的每个字符。因此,要么我必须使用 javascript 字符串生成我的正则表达式,要么使用看起来确实可以做到这一点的 RegExp 函数。
  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
  • 使用 JavaScript,这是您能做的最好的事情。在所有 Perl 衍生的风味中,它是最有限的。您对针对其他口味的答案感兴趣吗?

标签: javascript regex


【解决方案1】:

虽然正则表达式可以简化为:

/\{("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=\})/g

收件人:

/{("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=,)|,("(?:[^\\"]+|\\.)*")(?=})/g

删除 {} 的转义,因为它不是 JavaScript 的正则表达式引擎所必需的。

这不可能在 JavaScript 中删除您显式重复的模式 ("(?:[^\\"]+|\\.)*")

JavaScript 不支持基于 PCRE(PHP、C++、Perl 等)正则表达式引擎支持的所有相同正则表达式功能。

例如在 PHP / C++ 中你可以这样做:

{("(?:[^\\"]+|\\.)*")(?=,)|,((?1))(?=,)|,((?1))(?=})

对于 Perl 5.22,您需要再次转义 {,使其看起来像这样:

m/\{("(?:[^\\"]+|\\.)*")(?=,)|,((?1))(?=,)|,((?1))(?=})/g

(?1) 是一个子例程调用,用于匹配捕获组1 中的正则表达式,在本例中为("(?:[^\\"]+|\\.)*")

【讨论】: