zoukankan      html  css  js  c++  java
  • .net中的正则表达式使用高级技巧 (三)

    上篇:
    .net中的正则表达式使用高级技巧 (一)
    .net中的正则表达式使用高级技巧 (二)

    反向引用

    反向引用,指把匹配出来的组引用到表达式本身其它地方,比如,在匹配HTML的标记时,我们匹配出一个<a>,我们要把匹配出来的a引用出来,用来找到</a>,这个时候就要用到反向引用。
    语法
        a、反向引用编号的组,语法为\number
        b、反向引用命名的组,语法为\k<name>
    举例
        a、匹配成对的HTML标签

    @"<(?<tag>[^\s>]+)[^>]*>.*</\k<tag>>"        

        b、匹配两个两个重叠出现的字符  

            public static void Main()
            
    {    
                
    string s = "aabbc11asd";
                Regex reg 
    = new Regex(@"(\w)\1");
                MatchCollection matches 
    = reg.Matches(s);
                
    foreach(Match m in matches)
                    Console.WriteLine(m.Value);
                Console.ReadLine();
            }
          

    返回结果为aa bb 11 

    辅助匹配组

    以下几种组结构,括号中的Pattern都不作为匹配结果的一部分进行保存
        1、正声明(?=)
        涵义:括号中的模式必须出现在声明右侧,但不作为匹配的一部分

            public static void Main()
            
    {    
                
    string s = "C#.net,VB.net,PHP,Java,JScript.net";
                Regex reg 
    = new Regex(@"[\w\#]+(?=\.net)",RegexOptions.Compiled);
                MatchCollection mc 
    = reg.Matches(s);
                
    foreach(Match m in mc)
                    Console.WriteLine(m.Value); 
                Console.ReadLine();
                
    //输出 C# VB JScript
            }

        可以看到匹配引擎要求匹配.net,但却不把.net放到匹配结果中
        2、负声明(?!)
         涵义:括号中的模式必须不出现在声明右侧
            下例演示如何取得一个<a>标签对中的全部内容,即使其中包含别的HTML tag

            public static void Main()
            

                
    string newsContent = @"url:<a href=""1.html""><img src=""1.gif"">test<span style=""color:red;"">Regex</span></a>.";
                Regex regEnd 
    = new Regex(@"<\s*a[^>]*>([^<]|<(?!/a))*<\s*/a\s*>",RegexOptions.Multiline);
                
                Console.WriteLine(regEnd.Match(newsContent).Value);
    //Result: <a href="1.html"><img src="1.gif">test<span style="color:red;">Regex</span></a>
                Console.ReadLine();
            }

        3、反向正声明(?<=) 
        涵义:括号中的模式必须出现在声明左侧,但不作为匹配的一部分
        4、反向负声明(?<!)
        涵义:括号中的模式必须不出现在声明左侧

    非回溯匹配
    语法:(?>)
    涵义:该组匹配后,其匹配的字符不能通过回溯用于后面的表达式的匹配。呵呵,光看这句话肯定搞不懂,我当初为了搞懂这个也花了不少的时间,还是通过实例来说明吧:
    "www.csdn.net" 可以通过@"\w+\.(.*)\.\w+"来匹配,却不能通过@"\w+\.(?>.*)\.\w+"来匹配!为什么呢?

    原因是正则匹配是贪婪的,匹配时它会尽可能多的匹配最多的结果,所以,上例两个正则式中的.*都会把csdn.net匹配完, 这个时候,第一个表达式在开始匹配时发现\.\w+没得字符给它匹配了,所以它会进行回溯,所谓回溯,就是把.*匹配的结果往回推,回推留出来的字符再用来匹配\.\w+,直到\.\w+匹配成功,整个表达式返回成功的匹配结果。而第二个表达式,因使用的是非回溯匹配,所以,.*匹配完后,不允许通过回溯来匹配\.\w+,所以整个表达式匹配失败。

    请注意,回溯匹配是很浪费资源的一种匹配方式,所以,请尽量避免您的正则式要通过回溯来成功匹配,如上例,可以换成@"\w+\.([^\.]+\.)+\w+"+"

    下一篇:.net中的正则表达式使用高级技巧 (四)

  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/think/p/regexexpressionsyntax3.html
Copyright © 2011-2022 走看看