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

时间:2021-05-11 09:56:54

标签: php regex preg-match

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

<块引用>

[[ 图片:Justus Sustermans - 伽利略·伽利莱的肖像 (Uffizi).jpg|left|thumb|upright|[[Galileo]] 通常被称为 [[现代天文学]]之父,[[贾斯图斯]的肖像 萨斯特曼]]]]

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

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

但它在第一个 ]] 处停止。

Fiddle

2 个答案:

答案 0 :(得分:5)

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

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

test cases


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

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

test cases

答案 1 :(得分:2)

你可以使用

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

参见regex demo

详情

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

注意:如果您确定只能有一个嵌套级别的双方括号,您可以使用

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

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

相关问题