首页 > 解决方案 > 正则表达式匹配一个单词但不在反引号内

问题描述

这是不同段落的示例

Upgrade is the first word in this paragraph.
In this paragraph, upgrade is the last word.
And this paragraph endsupgrade with upgrade.
But I don't want to upgradefind that word in this command `gigalixir:upgrade`.

如您所见,上述四行中有 6 个升级字实例。我试图找到除最后一个之外的所有升级词(因为该词在反引号内的命令中)。我也不想找到不独立的升级词。

因此,在上面的句子中,应选择以下带有双 * 标记的单词:

**Upgrade** is the first word in this paragraph.
In this paragraph, **upgrade** is the last word.
And this paragraph endsupgrade with **upgrade**.
But I don't want to upgradefind that word in this command `gigalixir:upgrade`.

我试过这个简单的正则表达式:

/\bupgrade\b/gi

这选择了所有独立的词,但我想忽略反引号内的升级词。

注意:我不想使用lookahead 或lookbehind,因为我在浏览器中执行这个正则表达式,除了chrome 之外的任何浏览器都不支持。

标签: javascriptregex

解决方案


您可以匹配反引号内的字符串并跳过它们,并且仅将upgrade所有其他上下文中的单词作为整个单词匹配:

const text = 'Upgrade is the first word in this paragraph.\nIn this paragraph, upgrade is the last word.\nAnd this paragraph endsupgrade with upgrade.\nBut I don\'t want to upgradefind that word in this command `gigalixir:upgrade`.';
const regex = /(`[^`]*`)|\bupgrade\b/gi;
console.log(text.replace(regex, (x,y) => y || `**${x}**`));

(`[^`]*`)|\bupgrade\b则表达式匹配

  • (`[^`]*`)- 捕获第 1 组(这将有助于稍后分析匹配结构):反引号、除反引号外的零个或多个字符以及反引号
  • |- 或者
  • \bupgrade\b- 一个完整的单词(由于标志upgrade,不区分大小写)。i

.replace(regex, (x,y) => y || `**${x}**`)意味着在找到匹配项后,将匹配项传递给箭头函数,其中x是整个匹配项,并且y是第 1 组的值。如果第 1 组值匹配,则使用其值替换匹配项,否则,整个匹配项用双星号包裹。

或者,您可以使用带有负前瞻的已知解决方法,该解决方法仅在字符串中有成对数量的反引号时才有效:

\bupgrade\b(?=(?:[^`]*`[^`]*`)*[^`]*$)

请参阅正则表达式演示

(?=(?:[^`]*`[^`]*`)*[^`]*$)前瞻匹配紧随其后的位置

  • (?:[^`]*`[^`]*`)*除反引号外的任何零个或多个字符的零个或多个重复,然后是一个反引号,然后是除反引号之外的任何零个或多个字符,再次是一个反引号
  • [^`]*- 除反引号外的任何零个或多个字符
  • $- 字符串结束。

推荐阅读