环境:ASP.net
表达式:(?<=(&nbsp;)*)(?!Now)[^<]*
原字符串:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most问题:
为何匹配的是整个字符串,而不是What aspect of Mr. Zhang interests you most,"*"默认不是贪婪的么?请高手帮忙解释下。

解决方案 »

  1.   


                    string listIssue = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most";
                    Regex re = new Regex(@"(&nbsp;)+(?<text>.*)", RegexOptions.IgnoreCase);
                    Match mc = re.Match(listIssue);                while (mc.Success)
                    {
                        Response.Write(mc.Groups["text"] + "<br/>");
                        mc = mc.NextMatch();
                    }
                    Response.End();
      

  2.   


    匹配完毕后调用一下下面的方法就可以了,不必要什么内容都要用正则实现。结合其他方法使用会更快。
    ASP.NET 去除所有HTML标记///   <summary>   
      ///   去除HTML标记   
      ///   </summary>   
      ///   <param   name="NoHTML">包括HTML的源码   </param>   
      ///   <returns>已经去除后的文字</returns>   
      public   static   string   NoHTML(string   Htmlstring)   
      {   
      //删除脚本   
      Htmlstring   =   Regex.Replace(Htmlstring,@"<script[^>]*?>.*?</script>","",RegexOptions.IgnoreCase);   
      //删除HTML   
      Htmlstring   =   Regex.Replace(Htmlstring,@"<(.[^>]*)>","",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"([/r/n])[/s]+","",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"-->","",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"<!--.*","",RegexOptions.IgnoreCase);   
        
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(quot|#34);","/"",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(amp|#38);","&",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(lt|#60);","<",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(gt|#62);",">",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(nbsp|#160);","   ",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(iexcl|#161);","/xa1",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(cent|#162);","/xa2",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(pound|#163);","/xa3",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,@"&(copy|#169);","/xa9",RegexOptions.IgnoreCase);   
      Htmlstring   =   Regex.Replace(Htmlstring,   @"&#(/d+);","",RegexOptions.IgnoreCase);   
        
      Htmlstring.Replace("<","");   
      Htmlstring.Replace(">","");   
      Htmlstring.Replace("/r/n","");   
      Htmlstring=HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();   
        
      return   Htmlstring;   
      }
      

  3.   

    贪婪匹配:
     
    private const string HOT_CITY_CODE = @"<span class=""fred"">.*?</span>";
    <span class="fred"><a href="http://tj.soufun.com/" target="_blank">天津</a>
    <a href="http://taiyuan.soufun.com/" target="_blank">太原</a>
    <a href="http://ts.soufun.com/" target="_blank">唐山</a></span>
     
    能在html中截取到这一段代码
     
    如果这段html代码中有很多换行符,则应该通过(.|\n)*?的方式
      

  4.   

    楼主应该理解一下环视的概念。
    分析下你的正则:首先由“(?<=(&nbsp;)*)”取得控制权,由位置0开始尝匹配,由于“(?<=(&nbsp;)*)”的长度不固定,所以会从当前位置向左逐字符查找,当然,也有可能正则引擎做了优化,先计算一下最小长度后向前查找,在这里“(?<=(&nbsp;)*)”至少需要0个字符,所以由当前位置向左查找0个字符,才开始尝试匹配;所以无论左边是什么都会匹配成功的。
      

  5.   

    (&nbsp;)*:匹配0次或多次,
    源字符串0位置处开始匹配时,匹配多次失败,匹配0次的时候成功,控制权交出,继续执行。
    (?!Now)0位置后面匹配Now匹配成功,[^<]+也匹配成功。
    所以匹配到整个字符串。具体详细讲解你看看过客的博客,里面啥都讲解了。
                    string str = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most";
                    Regex reg = new Regex(@"(?<=&nbsp;)(?!&nbsp).+");
                    Console.WriteLine(reg.Match(str).Value);
    //What aspect of Mr. Zhang interests you most
      

  6.   

    我再补充一下,原字符串是这样的:
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now you have 1 minute to prepare.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Talk about three detailed facts to show their difference.

    我是想要获取除了“Now you have 1 minute to”这个字符串以外的其他字符串。我不理解的是(?<=(&nbsp;)*)(?!Now)[^<]*,只会匹配0个“&nbsp;”(为什么?默认不是贪婪模式么?换成+,也就只有匹配一个)我如果想匹配多个“&nbsp;”,也就是找到“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now you have 1 minute to”中,Now 前面的位置的话,有什么好办法么?(目前如果用{6}限定的话,感觉不太好,未必前面都是6个Html空格。)
      

  7.   

    using System;
    using System.Net;
    using System.Collections.Generic;
    using System.Xml;
    using System.Text;
    using System.Text.RegularExpressions;namespace ConsoleApplication13
    {
        class Program
        {
            static void Main(string[] args)
            {
                string test = @"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now you have 1 minute to prepare.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Talk about three detailed facts to show their difference.";
                MatchCollection mc = Regex.Matches(test, @"(&nbsp;)*([^&]*)");
                foreach (Match m in mc)
                {
                    Console.WriteLine(m.Groups[2].Value);
                }
            }
        }
    }/*
    Now you have 1 minute to prepare.
    What aspect of Mr. Zhang interests you most?
    You may compare your high school math teacher with Mr. Zhang.
    Talk about three detailed facts to show their difference.
    */
      

  8.   


    ————我不想要“Now you have 1 minute to prepare.”这句话。
      

  9.   


    还有,我主要想知道:(?<=(&nbsp;)*)(?!Now)[^<]*,(?<=(&nbsp;)*)里面的*为何不是贪婪模式,麻烦解释一下。并不仅仅想要知道结果。谢谢
      

  10.   

    因为(?<=(&nbsp;)*)这里面,给&nbsp;分组了。分组的贪婪,应该就不是所有的了,就是最后捕获的那个。
      

  11.   

    并非是这样的,我试过,如果是+,捕获的是第一个&nbsp;后的位置。如果是*,捕获的是第一个&nbsp;前面的位置。没有找到满意的答案,我结贴了。
      

  12.   

    额= =昨天有事忙,没在继续上csdn回复。上面不是有回答了吗?
    lz是在纠结
    (?<=(&nbsp;)+)和(?<=(&nbsp;)*)吗?
    首先正则总是单字符匹配的,也就是从第0个位置开始一个字符一个字符匹配
    当在位置0的时候,正则(?<=(&nbsp;)*),这个的最小字符是0,因为匹配0次到多次。
    所以0位置匹配成功了。控制权交出,继续执行下个表达式...接下去就不说了
    而(?<=(&nbsp;)+)最小字符是4,因为是匹配1次到多次
    当在0位置的时候匹配失败,到位置5,也就是;的时候匹配成功,
    而(?<=exp)是个零宽断言,意思也就是前面是exp,而在5位置的时候匹配成功了,所以从5继续匹配
    这样也就匹配第一&nbsp;后的位置如果还不明白的话你继续回复。我有上来在回帖。
      

  13.   

    谢谢您的继续关注,我主要纠结于(?<=(&nbsp;)+),环视中的量词"*"和"+",为什么不是贪婪的。
    比方说:a*b,如果匹配aaaaab,a*会一直匹配到最后一个a,这里的(&nbsp;)*,为什么不像a*一样,
    可以匹配到最后一个“&nbsp;”呢?
    比如:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang.
    我希望,该子表达式能够一直匹配到“You may compare your...”前面的位置,也就是最后一个&nbsp;后面的位置。如果用{6}来限制是可以做到的,但是我觉得不太好。因为前面的空格格式未必都是6个。请指教:)
      

  14.   

    先说
    string str="aaaaab"
    Regex reg = new Regex(@"a*b");
    这个是普通的正则,也就是匹配0个或多个a和一个b
    首先从0位置处开始匹配,匹配字符串a,匹配成功,一直匹配到b,也就是整个字符串
    这个理解应该没问题吧?
    而(?<=(&nbsp;)*)(?!Now)[^<]*这个表达式
    先看(?<=(&nbsp;)*)逆序肯定环视,也可以理解为(?<=exp)exp2,exp2的前面为exp
    而(&nbsp;)*为匹配0次或多次。
    (?<=(&nbsp;)*)开始匹配,当在0的位置时,0位置的前面为什么都没有,也就是匹配(&nbsp)*0次,
    匹配成功,匹配成功(?<=(&nbsp;)*)这个就交出控制权,执行(?!Now)[^<]*
    (?!Now)在位置1处匹配为不是Now的值,匹配成功,然后继续执行[^<]*。
    匹配不是<的多个数,也匹配成功。
    所以返回的是从0开始到结尾的字符串明白了?
      

  15.   


                string str = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang.";
                Regex reg = new Regex(@"(?:&nbsp;)*((?:(?!&nbsp).)+)");
                Console.WriteLine("{0}\r\n{1}", reg.Match(str).Value, reg.Match(str).Groups[1].Value);
      

  16.   

    我是不是可以理解为在逆序肯定环视里,(&nbsp;)*,不是贪婪模式?【你的代码中(?:&nbsp;)*,这里的*就是贪婪的,可以匹配连续的&nbsp;】另外,如果,我要排除后面的"Now you have 1 minute to prepare.",应该怎么写?
      

  17.   

    补充:
    原字符串为:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now you have 1 minute to prepare.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Talk about three detailed facts to show their difference.
      

  18.   

    你不要管是不是贪婪的,因为任何字符串(?<=(...)*)来匹配这一个都会匹配成功。
    你应该按着我上面写的那个理解,从位置0开始匹配,匹配0次或多次。
    例如:
                string str = "aaaaaaaaab";
                Regex reg = new Regex(@"(?<=c*).*");
                Console.WriteLine(reg.Match(str).Value);
    这个匹配出来的为aaaaaaaaab
      

  19.   

                string str = @"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now you have 1 minute to prepare.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;What aspect of Mr. Zhang interests you most?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You may compare your high school math teacher with Mr. Zhang. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Talk about three detailed facts to show their difference.";
                Regex reg = new Regex(@"(?<=&nbsp;)(?!Now|&nbsp;).+?(?=&nbsp;|$)");
                foreach (Match m in reg.Matches(str))
                    Console.WriteLine(m.Value);