一个通用的解决方案是这个:
\[{3}(?=.*?\]{3}(?!\]))((?:(?!\]{3}(?!\])).)*)
上面写着
\[{3} # 3 opening square brackets
(?= # begin positive look-ahead ("followed by..."
.*?\]{3} # ...3 closing brackets, anywhere ahead (*see explanation below)
(?!\]) # negative look-ahead: no more ] after the 3rd one
) # end positive look-ahead
( # begin group 1
(?: # begin non-matching group (for atomic grouping)
(?! # begin negative look-ahead ("not followed by"):
\]{3} # ...3 closing square brackets
(?!\]) # negative look-ahead: no more ] after the 3rd one
) # end negative look-ahead
. # the next character is valid, match it
) # end non-matching group
) # end group 1 (will contain the wanted substring)
肯定的前瞻是一个保障条款,当长输入字符串中没有"]]]" 时,它允许表达式快速失败。
一旦确定"]]]" 将在字符串中的某个点跟随,否定的前瞻确保表达式正确匹配这样的字符串:
[[[foo [some text] bar]]]
^
+-------- most of the other solutions would stop at this point
此表达式检查每个字符是否跟随三个],因此在此示例中它将包括" bar"。
表达式的"no more ] after the 3rd one" 部分确保匹配不会过早结束,因此在这种情况下:
[[[foo [some text]]]]
匹配仍然是"foo [some text]"。
没有它,表达式会过早停止 ("foo bar [some text")。
副作用是我们不需要实际匹配"]]]",因为正向预测清楚地表明它们在那里。我们只需要匹配它们,负前瞻就可以很好地做到这一点。
请注意,如果您的输入包含换行符,则需要在“dotall”模式下运行表达式。
另请参阅:http://rubular.com/r/QFo9jHEh9d