大家好 我在一个小应用中碰到了一个小麻烦 虽然不是很影响实现但自己非常想弄明白所以特来求教
我希望实现的目的是在一段html代码中识别出自己需要的东西 html代码可能很长 其中一段片段会是类似如下格式
<ul class="lev1"><li><a href="link1">Link 1</a><span class="cnt"> (123)</span></li><li><a href="link2">Link 2</a><span class="cnt"> (456)</span></li></ul>
所以我写了个正则表达式想来进行匹配,我所感兴趣的是这部分代码中的几个关键部分 <a href>中的链接地址,显示的文字和span块中的文字,就是下面正则表达式中我加粗显示的部分
但下面代码运行的结果是matches集合中只有一个match 就是会在整个html文件中匹配出类似上面这种片段的整段 而没有在其中找到我希望直接拿到的子匹配 不知道该怎么修改 查了查资料不是说放在圆括号里面的部分会作为一个子匹配被自动捕获的么 该如何才能灵活控制要匹配哪部分 先谢过了~String pattern = @"<ul class=""lev1"">(?:<li><a href=""(.*)""(.*)</a><span class=""cnt""> \((.*)\)</span </li>)+</ul>";
                    MatchCollection matchs = Regex.Matches(originalinfo, pattern);
                    MessageBox.Show(matchs.Count.ToString());
                    foreach (Match nextmatch in matchs)
                        MessageBox.Show(nextmatch.Value);

解决方案 »

  1.   

    (?<info>exp)取的时候nextmatch.Groups["info"].Value.Trim();
      

  2.   

    (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) 
      

  3.   

    嗯 谢谢 我刚才也在试这个groups 这样可以取到 但是麻烦是现在这样子匹配是贪婪的 我怎么样才能设置取得最多的子匹配呢 也就是我希望把每一个a href="link1"里面的地址部分都取到,每一个Link 1 以及每一个数字都取到 现在这种情况下我的第一个(.*)就会匹配出从开头到最后一个 </a>之前的部分
    @"<ul class=""lev1"">(<li><a href=""(.*?)"">(.*?)</a><span class=""cnt""> \((.*?)\)</span></li>)+</ul>"  这里改成(.*?)效果好像也不理想多谢了~
      

  4.   

    这里改成(.*?)之后 第一个(.*?)的确不会匹配那么长的代码了 比如这里不会在匹配link1">Link 1 </a> <span class="cnt"> (123) </span> </li> <li> <a href="link2了
    但是groups里却只能取到 最后一组符合条件的匹配,就是groups里只有 link2,Link 2 ,456 这三个元素了
    link1相关的那些取不到
      

  5.   


    (?is)<li>[^<]*<a.*?(?:href=\")(?<href>[^\"]*)[^>]*>(?<hrefDesc>.*?(?=</a>)).*?(?:<span[^>]*>)(?<span>.*?(?=</span>))取href  hrefDesc  和span即可nextmatch.Groups["href"].Value.Trim(); nextmatch.Groups["hrefDesc"].Value.Trim(); nextmatch.Groups["span"].Value.Trim(); 
      

  6.   

    再次谢谢~ 不过这样的话需要做两次匹配了么 第一次先在整个html文档里匹配出大段 然后再在这段里循环match? 这里我有点想知道的一个问题是正则表达式里比如一个(?<name>aa.*aa)+ 那么 如果有多个匹配 就是+号>1的时候 怎么通过groups来取得所有这些值呢?
      

  7.   

    //借用你的代码
    String pattern = @" (? <name>aa.*aa)+ "; //匹配了N个
                        MatchCollection matchs = Regex.Matches(originalinfo, pattern); 
                        MessageBox.Show(matchs.Count.ToString()); 
                        foreach (Match nextmatch in matchs) 
                            MessageBox.Show(nextmatch.Groups["name"].Value); 
      

  8.   

    谢谢~ 我大概描述的不太清楚 我的情况是这是段html代码,包在<ul class=""lev1""></ul>里的 所以我用下面的pattern去匹配的话,matches中只有一个匹配,而且匹配的结果是一整段,里面包含了很多 <li></li>,而且这些<li></li>对的数量是不固定的
    String pattern = @" <ul class=""lev1"">(?: <li> <a href=""(.*)""(.*) </a> <span class=""cnt""> \((.*)\) </span </li>)+ </ul>"; 我现在是希望能不能在match以后能直接在某个数组比如groups里直接读到全部每个<li></li>对里我需要的3个内容就行了,而不必先match出整段,然后再在这段里再做一次循环match,每次match一个<li></li>对,大概也是自己想偷懒,觉得这样比较省力...
      

  9.   

    你干脆把你的匹配源HTML贴出来。 然后告诉大家你要获得什么内容。