正则应用之 逆序环视探索 .(4)


string test = @"<font color=""#008000""> ** 这里是不固定的字符串1 ** </font>
<font color=""#008000""> ** 这里是不固定的字符串2 ** </font>
<font color=""#008000""> ** 这里是不固定的字符串3 ** </font> ";
MatchCollection mc = Regex.Matches(test, @"(?<=<font[\s\S]*?>)([\s\S]*?)(?=</font>)");
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n---------------\n";
}
/*--------输出--------
** 这里是不固定的字符串1 **
---------------
<font color="#008000"> ** 这里是不固定的字符串2 **
---------------
<font color="#008000"> ** 这里是不固定的字符串3 **
---------------
*/


其实真正让人费解的是这里的逆序环视的匹配结果,为了更好的说明问题,改下正则。
string test = @"<font color=""#008000""> ** 这里是不固定的字符串1 ** </font>

复制代码 代码如下:


<font color=""#008000""> ** 这里是不固定的字符串2 ** </font>
<font color=""#008000""> ** 这里是不固定的字符串3 ** </font> ";
MatchCollection mc = Regex.Matches(test, @"(?<=(<font[\s\S]*?>))([\s\S]*?)(?=</font>)");
for(int i=0;i<mc.Count;i++)
{
richTextBox2.Text += "第" + (i+1) + "轮成功匹配结果:\n";
richTextBox2.Text += "Group[0]:" + m.Value + "\n";
richTextBox2.Text += "Group[1]:" + m.Groups[1].Value + "\n---------------\n";
}
/*--------输出--------
第1轮成功匹配结果:
Group[0]: ** 这里是不固定的字符串1 **
Group[1]:<font color="#008000">
---------------
第2轮成功匹配结果:
Group[0]:
<font color="#008000"> ** 这里是不固定的字符串2 **
Group[1]:<font color="#008000"> ** 这里是不固定的字符串1 ** </font>
---------------
第3轮成功匹配结果:
Group[0]:
<font color="#008000"> ** 这里是不固定的字符串3 **
Group[1]:<font color="#008000"> ** 这里是不固定的字符串2 ** </font>
---------------
*/


对于第一轮成功匹配结果应该不存在什么疑问,这里不做解释。
第一轮成功匹配结束的位置是第一个“</font>”前的位置,第二轮成功匹配尝试就是从这一位置开始。
首先由“(?<=<font[\s\S]*?>)”取得控制权,向左查找6个字符后开始尝试匹配,由于“<”会匹配失败,所以会一直尝试到位置0处,这时“<font”是可以匹配成功的,但是由于“<font[\s\S]*?>”要匹配成功,匹配的结束位置必须是第一个“</font>”前的位置,所以“>”是匹配失败的,这一位置整个表达式匹配失败。
正则引擎传动装置向右传动,直到第一个“</font>”后的位置,“<font[\s\S]*?>”匹配成功,匹配开始位置是位置0,匹配结束位置是第一个“</font>”后的位置,“<font[\s\S]*?>”匹配到的内容是“<font color="#008000"> ** 这里是不固定的字符串1 ** </font>”,其中“[\s\S]*?”匹配到的内容是“color="#008000"> ** 这里是不固定的字符串1 ** </font”,后面的子表达式继续匹配,直到第二轮匹配成功。
接下来的第三轮成功匹配,匹配过程与第二轮基本相同,只不过由于使用的是非贪婪模式,所以“<font[\s\S]*?>”在匹配到“<font color="#008000"> ** 这里是不固定的字符串2 ** </font>”时匹配成功,就结束匹配,不再向左尝试匹配了。
接下来看下贪婪模式的匹配结果。

复制代码 代码如下:


string test = @"<font color=""#008000""> ** 这里是不固定的字符串1 ** </font>
<font color=""#008000""> ** 这里是不固定的字符串2 ** </font>
<font color=""#008000""> ** 这里是不固定的字符串3 ** </font> ";
MatchCollection mc = Regex.Matches(test, @"(?<=(<font[\s\S]*>))([\s\S]*?)(?=</font>)");
for(int i=0;i<mc.Count;i++)
{
richTextBox2.Text += "第" + (i+1) + "轮成功匹配结果:\n";
richTextBox2.Text += "Group[0]:" + m.Value + "\n";
richTextBox2.Text += "Group[1]:" + m.Groups[1].Value + "\n---------------\n";
}
/*--------输出--------
第1轮匹配结果:
Group[0]: ** 这里是不固定的字符串1 **
Group[1]:<font color="#008000">
---------------
第2轮匹配结果:
Group[0]:
<font color="#008000"> ** 这里是不固定的字符串2 **
Group[1]:<font color="#008000"> ** 这里是不固定的字符串1 ** </font>
---------------
第3轮匹配结果:
Group[0]:
<font color="#008000"> ** 这里是不固定的字符串3 **
Group[1]:<font color="#008000"> ** 这里是不固定的字符串1 ** </font>
<font color="#008000"> ** 这里是不固定的字符串2 ** </font>
---------------
*/
仅仅是一个字符的差别,整个表达式的匹配结果没有变化,但匹配过程差别却是很大的。
那么如果想得到下面这种结果要如何做呢?
/*--------输出--------
** 这里是不固定的字符串1 **
---------------
** 这里是不固定的字符串2 **
---------------
** 这里是不固定的字符串3 **
---------------
*/


把量词修饰的子表达式的匹配范围缩小就可以了。

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wfyzjx.html