使用正则表达式解析方括号

4

我一直对正则表达式感到困惑。虽然我寻求了帮助,但我似乎找不到我需要的。

我有一些文本块,遵循以下模式:

[php] ... 这里可以是任何类型的代码示例 [/php]

我需要:

  • 检查方括号,其中可以包含20-30个编程语言名称(phpruby等)。
  • 需要获取在打开和关闭括号之间的所有代码。

我已经制定了以下正则表达式:

#\[([a-z]+)\]([^\[/]*)\[/([a-z]+)\]#i

这基本上匹配了所有内容。但是,当代码示例包含方括号时,它会出错。如何修改它以使打开/关闭括号之间的任何字符都能被匹配并用于后续使用?


你是否会有类似 [php] print "[/php]"; [/php] 这样的东西?如果是这样,正则表达式帮助不大。要检测这样的内容所需的正则表达式将非常复杂,最好使用整个解析器。 - cHao
4个回答

5
这是你需要的正则表达式。它能匹配标签,即使标签是偶数个,所以一个php标签只会结束一个php标签。
/\[(\w+)\](.*?)\[\/\1\]/s

或者如果你想明确匹配标签,你可以使用...
$langs = array('php', 'python', ...); 

$langs = implode('|', array_map('preg_quote', $langs));

preg_match_all('/\[(' . $langs . ')\](.*?)\[\/\1\]/s', $str, $matches);

1
这也捕获了 .*? 部分,这会破坏反向引用。 - Aaa
@重构 这会如何破坏反向引用? - alex
\1之前缺少了一个/ - manojlds

1

以下代码可以正常运行:

\[([a-z]+)\].*\[/\1\]

如果您不想去除贪婪模式,可以这样做:

\[([a-z]+)\].*?\[/\1\]

你所要做的就是检查闭合标签和开放标签是否具有相同的文本(在这种情况下,两者都是相同的编程语言),并且你可以使用\1来实现匹配之前匹配的第一个组号:([a-z]+)


0
为什么不使用类似下面的东西:
\[php\].*?\[/php\]

我不明白为什么你想要使用[a-z]+来作为标签,应该只有php或其他少量的标签。保持简单就好。

实际上你可以使用:

\[(php)\].*?\[/(\1)\]

这样你就可以匹配开放和关闭标签。否则,你将会匹配到随机的开放和关闭标签。添加其他的,比如说,我不知道,js等,作为php|js等。


0
使用反向引用来引用已经在正则表达式中匹配的内容:
\[(\w+)\].*?\[/\1\]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接