如果在它之前的任何地方找到字符串 B,则尝试匹配字符串 A

Trying to match string A if string B is found anywhere before it

我想做的是,如果一个字符串包含一些以“!”开头的子字符串封装在“[”和“]”中,通过 space 将这些括号与字符串的其余部分分开,例如“[!foo]” --> “[ !foo ]”、“[!bar]” --> “[ !bar ]” 等。由于该子字符串可以是可变长度,我认为这必须通过正则表达式。我的想法是分两步进行 - 首先分开第一个支架,然后分开第二个支架。

第一个不难;正则表达式只是 \[!,所以我可以在 Javascript 中做 str = str.replace(/\[!/g, "[ !");。这是第二部分我无法开始工作。

因为现在,如果字符串文字“[ !”,我需要匹配“]”在它之前 任何地方 找到。所以一个简单的正面后视不匹配,因为它只直接看后面:(?<=\Q[ !\E)\]不匹配。

我仍然不明白为什么,但我不允许让正后视非固定长度; (?<=\Q[ !\E.*)\] 在控制台中抛出错误 Syntax Error: Invalid regular expression: missing /this regex debugger 产生模式错误,解释 "A quantifier inside a lookbehind makes it non-fixed width"。

在lookbehind和捕获组之间放置一个非固定宽度的非捕获组是行不通的; (?<=\Q[ !\E)(?:.*)\] 不匹配。

有一件事是行不通的,就是试图匹配“[ !”在字符串的开头,因为整个“[!foo]”字符串实际上是 本身 一个更大字符串的子字符串,而不是开头。

我错过了什么?

使用 2 个正面环视,您可以断言左边是左方括号 (?<=\[)

然后使用 negated character class ![^[\]]+ 前面加上感叹号来匹配除 ] 之外的任何字符,并使用 (?=]) 断言右边的是右方括号

请注意,在 Javascript 中,lookbehind 尚未得到广泛支持。

(?<=\[)![^[\]]+(?=])

replacement中使用匹配的子串$&

Regex demo

[
  "[!foo]",
  "[!bar]"
].forEach(s =>
  console.log(s.replace(/(?<=\[)![^[\]]+(?=])/g, " $& "))
)


或者您也可以改用 3 个捕获组:

(\[)(![^\]]+)(\])

在替换中使用

  

Regex demo

[
  "[!foo]",
  "[!bar]"
].forEach(s =>
  console.log(s.replace(/(\[)(![^\]]+)(\])/g, "  "))
)

您可以使用此正则表达式:\[!([^]]+)\] 和此替换字符串 [! ]

解释:

正则表达式:

  • \[!:匹配以 [!
  • 开头
  • ([^]]+):在组 1 中捕获所有不是 ]
  • 的字符
  • \]: 匹配]

替换:用[!{第1组的内容}].

替换完整匹配

Regex Demo

希望对您有所帮助。