【问题标题】:How to replace a capture group instead of the full match in a RegEx?如何在正则表达式中替换捕获组而不是完整匹配?
【发布时间】:2019-09-13 22:51:24
【问题描述】:

我有这个代码:

let x = "the *quick* brown fox";

let y = x.replace(/[^\\](\*)(.*)(\*)/g, "<strong>$2</strong>");

console.log(y);

它将*quick* 替换为&lt;strong&gt;quick&lt;/strong&gt;

问题是我还想用反斜杠转义它,这样\*quick* 就不会被转换为&lt;strong&gt;quick&lt;/strong&gt;

我通过要求前一个字符在正则表达式中不是斜杠来做到这一点。

不幸的是,这也消除了结果中的那个字符。

所以结果最终是:

the&lt;strong&gt;quick&lt;/strong&gt; brown fox(注意空格)

我想也许我可以将正则表达式的后半部分包装在一个捕获组中并仅替换它,但据我所知,Javascript 的替换功能仅适用于完整匹配。

有没有办法解决这个问题?我避免使用成熟的 Markdown 库,因为我只需要处理几种情况(粗体和斜体),所以我尽量保持简单。

【问题讨论】:

  • 您可以捕获它([^\\])(\*)(.*)(\*) 并替换为$1&lt;strong&gt;$3&lt;/strong&gt;,但这也不正确,因为反斜杠可以自己转义。贪婪的.* 可能也不会工作得那么好……然后是混合强调标记……你可能应该使用一个库。或者至少写一些不是基于用正则表达式替换的东西。
  • 是的,在我的测试中,我注意到$1&lt;strong&gt;$3&lt;/strong&gt; 非常接近,但也不是很接近。我有点希望我能解决这个小问题,而不是必须迁移到一个成熟的库。

标签: javascript regex string markdown


【解决方案1】:

使用否定的lookbehind 使字符不包含在匹配中。这也将允许它在字符串的开头匹配(您的正则表达式要求在匹配之前有一个字符)。

let x = "the *quick* brown fox";
let y = x.replace(/(?<!\\)(\*)(.*)(\*)/g, "<strong>$2</strong>");
console.log(y);

x = "the \\*quick* brown fox";
y = x.replace(/(?<!\\)(\*)(.*)(\*)/g, "<strong>$2</strong>");
console.log(y);

Negative lookbehinds 是一项新的 JavaScript 功能,如果您必须支持旧版浏览器,请将其前面的字符放入另一个捕获组,然后将其复制到替换中。解决开头匹配的问题,可以匹配字符串的开头或者非反斜杠。

let x = "the \\*quick* brown fox";
let y = x.replace(/(^|[^\\])(\*)(.*)(\*)/g, "$1<strong>$3</strong>");
console.log(y);

x = "the *quick* brown fox";
y = x.replace(/(^|[^\\])(\*)(.*)(\*)/g, "$1<strong>$3</strong>");
console.log(y);

【讨论】:

  • 太棒了,这很好用!是的,我看到负面的向后看只有 71% 的浏览器支持。但是替代解决方案只有 2 个额外的字符,所以还不如直接使用它?除非 babel 为你将负面的lookbehind转换为它?
  • 不,babel 不会转换这个,有太多的复杂性。
  • Okie dokie 我将使用第二个选项。谢谢!
  • 对不起,我想我注意到了一个问题(虽然不确定是否可以修复?)。如果您输入反斜杠,则反斜杠仍然存在于输出中。理想情况下,the \*quick* brown fox 的输入会输出the *quick* brown fox,(没有反斜杠,没有强),你知道吗?
  • 其实没关系,我想我已经修好了。在我通过正则表达式运行它之后可以做y = y.replace(/\\/g, "");
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 2021-05-28
  • 2021-11-14
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
相关资源
最近更新 更多