在[]之间匹配任何内容的正则表达式

17

我需要找到[]的正则表达式

例如,如果字符串是- Hi [Stack],这是我需要[Find]的[Tag]。

它应该返回Stack、Tag、Find。


2
是否可以有嵌套匹配:foo [bar[baz]] done,你想要获取 bar[baz] 吗?或者是 foo [bar\\]baz] done,你想要获取 bar]baz 吗?在 [] 之间可以有换行吗? - Bart Kiers
5个回答

53

非常简单,只需要(1)使用反斜杠转义括号,以及(2)使用(.*?)来捕获内容。

\[(.*?)\]

圆括号是一个捕获组,它们捕获其内容以供以后使用。问号跟在.*后面,使匹配变为非贪婪模式。这意味着它将匹配可能的最短匹配,而不是最长匹配。贪婪和非贪婪的区别出现在一行中有多个匹配项的情况下:

Hi [Stack], Here is my [Tag] which i need to [Find].
   ^______________________________________________^

贪婪匹配会在两个方括号之间找到尽可能长的字符串。这样并不正确。非贪婪匹配会找到最短的字符串:

Hi [Stack], Here is my [Tag] which i need to [Find].
   ^_____^

无论如何,代码最终会看起来像

string regex = @"\[(.*?)\]";
string text  = "Hi [Stack], Here is my [Tag] which i need to [Find].";

foreach (Match match in Regex.Matches(text, regex))
{
    Console.WriteLine("Found {0}", match.Groups[1].Value);
}

1
@henning 是的,等价的Python代码具有相同的输出 - John Kugelman
“相当简单”并不是那么简单。只需在字符串中放入一个ASCII字符,就可以看到它自己了。例如,对于这个字符串什么也不会发生。"Hi [St" + (char) 10 +"ack]" - Farid
@Farid 当然不行。(char) 10 是一个 \n 换行符。它与我的答案无关。 - John Kugelman
你说得对,这确实是一个换行符,但问题特别指出“任何之间的内容”。我认为\[(?s)(.*)\]更准确,至少对于未来的读者而言。 - Farid

3
\[([\w]+?)\]

应该可以工作。如果需要包括特殊字符,您可能需要更改匹配组。


这比当前标记的答案更好,因为它对诸如此类的内容有更好的控制:“Test [test] [ test [test]”。标记的答案将包括匹配中的杂项[,而这个正则表达式不会。 - StronglyTyped

3

根据您所指的环境不同:

\[([^\]]+)]

0

处理多个嵌套括号的.NET语法:

\[ ( (?: \\. | (?<OPEN> \[) | (?<-OPEN> \]) | [^\]] )*? (?(OPEN)(?!)) ) \]

此代码计算OPEN中打开的[部分的数量,并仅在最后OPEN为0时成功。


0

我遇到了类似的问题,发现这个也可以解决。

\[\w{1,}\]

\w 表示元字符Metacharacter。这将匹配1个或多个单词字符。

使用n{X,}量词可以匹配任何字符串,其中您可以获得不同的数量。故意省略第二个数字后,表达式表示要匹配1个或多个字符。


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