110,533
社区成员
发帖
与我相关
我的任务
分享
string test = "abcdefghijkl";
Regex reg = new Regex(@"(?<chars>[a-z]{2})+");
Match m = reg.Match(test);
if (m.Success)
{
richTextBox2.Text += "匹配结果:" + m.Value + "\n";
richTextBox2.Text += "Group:" + m.Groups["chars"].Value + "\n";
}
//输出
匹配结果:abcdefghijkl
Group:kl
从m.Groups["chars"].Value的输出上看,似乎确实是只保留了一个匹配内容,但却忽略了一个事实,Group实际上是Capture的一个集合string test = "abcdefghijkl";
Regex reg = new Regex(@"(?<chars>[a-z]{2})+");
Match m = reg.Match(test);
if (m.Success)
{
richTextBox2.Text += "匹配结果:" + m.Value + "\n";
richTextBox2.Text += "Group:" + m.Groups["chars"].Value + "\n--------------\n";
foreach (Capture c in m.Groups["chars"].Captures)
{
richTextBox2.Text += "Capture:" + c + "\n";
}
}
//输出
匹配结果:abcdefghijkl
Group:kl
--------------
Capture:ab
Capture:cd
Capture:ef
Capture:gh
Capture:ij
Capture:kl
平时应用时可能会忽略这一点,因为很少遇到一个捕获组先后匹配多个子串的情况,而在一个捕获组只匹配一个子串时,Group集合中就只有一个Capture元素,所以内容是一样的。string test = "abcdefghijkl";
Regex reg = new Regex(@"(?<chars>[a-z]{2})");
Match m = reg.Match(test);
if (m.Success)
{
richTextBox2.Text += "匹配结果:" + m.Value + "\n";
richTextBox2.Text += "Group:" + m.Groups["chars"].Value + "\n--------------\n";
foreach (Capture c in m.Groups["chars"].Captures)
{
richTextBox2.Text += "Capture:" + c + "\n";
}
}
//输出
匹配结果:ab
Group:ab
--------------
Capture:ab
捕获组保存的是一个集合,而不只是一个元素,这一知识点对于理解平衡组的匹配原理是有帮助的。string test = "abc";
Regex reg = new Regex(@"(?(?=a)\w{2}|\w)");
MatchCollection mc = reg.Matches(test);
foreach(Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}
//输出
ab
c
对于“(?(name)yes|no)”,如果命名捕获组“name”有捕获,则匹配“yes”子表达式,否则匹配“no”子表达式。这一语法最典型的一种应用是平衡组。string test = "a+(b*(c+d))/e+f-(g/(h-i))*j";
Regex reg = new Regex(@"\(((?<Open>\()|(?<-Open>\))|[^()])*(?(Open)(?!))\)");
MatchCollection mc = reg.Matches(test);
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}
//输出
(b*(c+d))
(g/(h-i))
下面来考察一下这个正则,为了阅读方便,写成宽松模式。Regex reg = new Regex(@"\( #普通字符“(”
( #分组构造,用来限定量词“*”修饰范围
(?<Open>\() #命名捕获组,遇到开括弧’Open’计数加1
| #分支结构
(?<-Open>\)) #狭义平衡组,遇到闭括弧’Open’计数减1
| #分支结构
[^()]+ #非括弧的其它任意字符
)* #以上子串出现0次或任意多次
(?(Open)(?!)) #判断是否还有’Open’,有则说明不配对,什么都不匹配
\) #普通闭括弧
", RegexOptions.IgnorePatternWhitespace);
对于一个嵌套结构而言,开始和结束标记都是确定的,对于本例开始为“(”,结束为“)”,那么接下来就是考察中间的结构,中间的字符可以划分为三类,一类是“(”,一类是“)”,其余的就是除这两个字符以外的任意字符。string test = "a+(b*(c+d))/e+f-(g/(h-i))*j";
Regex reg0 = new Regex(@"\( #普通字符“(”
( #分组构造,用来限定量词“*”修饰范围
(?<Open>\() #命名捕获组,遇到开括弧Open计数加1
| #分支结构
(?<-Open>\)) #狭义平衡组,遇到闭括弧Open计数减1
| #分支结构
. #任意字符
)*? #以上子串出现0次或任意多次,非贪婪模式
(?(Open)(?!)) #判断是否还有'OPEN',有则说明不配对,什么都不匹配
\) #普通闭括弧
", RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = reg0.Matches(test);
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}
//输出
(b*(c+d))
(g/(h-i))
Regex reg1 = new Regex(@"\( #普通字符“(”
( #分组构造,用来限定量词“*”修饰范围
(?<Open>\() #命名捕获组,遇到开括弧’Open’计数加1
| #分支结构
(?<-Open>\)) #狭义平衡组,遇到闭括弧’Open’计数减1
| #分支结构
[^()]+ #非括弧的其它任意字符
)* #以上子串出现0次或任意多次
(?(Open)(?!)) #判断是否还有’Open’,有则说明不配对,什么都不匹配
\) #普通闭括弧
", RegexOptions.IgnorePatternWhitespace);