【问题标题】:regex to match the closing tags by ignoring inner tags正则表达式通过忽略内部标签来匹配结束标签
【发布时间】:2021-05-11 09:56:54
【问题描述】:

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

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

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

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

但它停在第一个]]

Fiddle

【问题讨论】:

  • @anubhava 匹配上面引用的整个文本(维基文本之外)。
  • 那么,您不需要实际捕获[[Image:]] 之间的文本吗?那你为什么要使用捕获组呢?

标签: php regex preg-match


【解决方案1】:

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

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

test cases


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

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

test cases

【讨论】:

    【解决方案2】:

    你可以使用

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

    请参阅regex demo

    详情

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

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

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

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

    【讨论】: