正则表达式通过忽略内部标签来匹配结束标签

regex to match the closing tags by ignoring inner tags

我想截取MediaWiki格式的图片标签,例如

[[ Image:Justus Sustermans - Portrait of Galileo Galilei (Uffizi).jpg|left|thumb|upright|[[Galileo]] is often referred to as the Father of [[modern astronomy]], portrait by [[Justus Sustermans]]]]

我必须忽略内部 [[...]] 以匹配整体(以粗体 [[]] 显示)。我想到了

\[\[Image:((?:[^]]*+(?:(?!\[\[)|(?R))*+)*+)\]\]

但它停在第一个 ]]

Fiddle

你可以使用

\[\[Image:((?:[^][]+|(\[\[(?:[^][]++|(?-1))*]]))*)]]

参见regex demo

详情:

  • \[\[Image: - 文字 [[Image: 字符串
  • ((?:[^][]+|(\[\[(?:[^][]++|(?-1))*]]))*) - 第 1 组:
    • (?:[^][]|(\[\[(?:[^][]++|(?-1))*]]))* - 零次或多次出现
      • [^][]+ - []
      • 以外的任何一个或多个字符
      • | - 或
      • (\[\[(?:[^][]++|(?-1))*]]) - 第 2 组(技术性的,用于递归):嵌套 [[]]
      • 之间的子字符串
  • ]] - ]] 字符串。

注意:如果你确定双方括号只能嵌套一层,可以使用

\[\[Image:([^][]*(?:\[\[[^][]*]][^][]*)*)]]

参见 this regex demo。在这里,([^][]*(?:\[\[[^][]*]][^][]*)*) 将除 [] 之外的任何零个或多个字符捕获到第 1 组中,然后匹配双方括号之间的零个或多个子字符串,并且内部没有方括号,并且然后 [].

以外的零个或多个字符

或者您可以寻找平衡的方括号,但使用环视限制两端的规则:

(?=\[\[Image:)(\[(?:[^][]|(?1))*])(?<=]])
  • (?=\[\[Image:) 前瞻搜索以 [[Image:
  • 开头的字符串
  • (\[(?:[^][]|(?1))*]) 使用递归平衡嵌套方括号
  • (?<=]]) 向后搜索以 ]]
  • 结尾的字符串

test cases


如果您不关心里面的括号是否平衡,只是想做一个假设并排除 [[ ]] 对。这个应该可以解决问题:

\[\[Image:(?:\[\[.*?]]|.)*?]]

test cases