用于捕获嵌套括号中的值的正则表达式

RegEx for capturing values in nested brackets

我试图使用正则表达式来匹配两个字符之间的内部文本,但我得到了错误的文本

我尝试使用 [A-z]* 而不是 .* 来仅匹配内部文本并且成功了。但是我也需要匹配非字母字符。

/\[?(,? ?\[(\[(.+)-(.+)\])\])\]?/g

这是我的正则表达式,我想匹配方括号之间的字符:

[[[hello-hello]],[[hi-hi]]]

加粗的字符是匹配的。

I'd expect to match [[[hello-hello]],[[hi-hi]]] in match 1 and [[[hello-hello]],[[hi-hi]]] in match two.

这是我想出的正则表达式:

\[+([a-z- A-Z]+)\]+

Demo

我会使用这样的东西:

\[(?!\[)([^\]]*)\]

这将匹配一个 [ 字符,如果后面没有跟一个 [ 字符的话。然后它将匹配任意数量的非 ] 字符,将它们捕获到第 1 组中。然后匹配 ] 个字符。

const text = "[[[hello-hello]],[[hi-hi]]]";
const regex = /\[(?!\[)([^\]]*)\]/g;
var match;

while (match = regex.exec(text)) {
  console.log(match);
}

或者,您可以省略捕获组并删除每个匹配项的第一个和最后一个字符。

const text = "[[[hello-hello]],[[hi-hi]]]";
const regex = /\[(?!\[)[^\]]*\]/g;

console.log(
  text.match(regex)
      .map(match => match.slice(1, -1))
);

如果需要 [] 之间的所有内容,那么我们可以将表达式简化为 maybe:

(?:\[+)(.+?)(?:\]+)

在这里,我们在此捕获组中捕获可能需要的子字符串:

(.+?)

然后,我们使用两个 non-capturing 组在其左右两侧添加两个边界:

(?:\[+)
(?:\]+)

演示

const regex = /(?:\[+)(.+?)(?:\]+)/g;
const str = `[[[hello-hello]]
[[hi-hi]]]
[[hi hi]]]`;
const subst = ``;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

正则表达式

如果不需要这个表达式,它可以是 regex101.com 中的 modified/changed。

正则表达式电路

jex.im 可视化正则表达式:

正则表达式

(?<=\[)([a-z- A-Z]+)(?=\])

(?<=\[):以括号开头,但不包含括号。

(?=\]):以括号结束,但不包含括号。

详细的解释可以在这个link.

中找到

您可以使用 1 个捕获组来捕获您的值。

连字符前后的值可以使用 negated character class \[([^][\n-]+ 匹配,而不是左括号或右括号、连字符或换行符。

在您的模式中,您使用了一个点来匹配除换行符以外的任何字符,因此否定字符 class 包含一个换行符以防止跨行。

\[([^\][\n-]+-[^\][\n-]+)]

说明

  • \[ 匹配 [
  • (开始抓包
    • [^\][\n-]+ 否定字符 class,匹配 1+ 次不是 ][- 或换行符
    • - 匹配 -
    • [^\][\n-]+ 匹配 1+ 次不是 ][- 或换行符
  • ) 关闭捕获组
  • ] 匹配 ] 字符

Regex demo

const regex = /\[([^\][\n-]+-[^\][\n-]+)]/g;
const str = `[[[hello-hello]],[[hi-hi]]]`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log(m[1]);
}