这类嵌套正则如何写?通过id属性获得一个标签块

王集鹄 2009-04-15 04:30:38
加精
需求:就是通过id获得一个html标签块。

要处理的字符串:
<html>
<body>
<div id="div1">
<div id="div2" style="background:Red;">
<div id="div3">
<table id="table1">
<tr>
<td>
<div id="div4" style="width:100p
x"></div>
</td>
</tr>
</table>
</div>
</div>
<div id="div5">
<a href="http://www.csdn.net">csdn</a>
</div>
</div>
<img src="http://www.csdn.net/Images/logo_csdn.gif"/>
</body>
</html>


输入输出样例1
输入:"div1"
输出:
<div id="div1">
<div id="div2" style="background:Red;">
<div id="div3">
<table id="table1">
<tr>
<td>
<div id="div4" style="width:100p
x"></div>
</td>
</tr>
</table>
</div>
</div>
<div id="div5">
<a href="http://www.csdn.net">csdn</a>
</div>
</div>


输入输出样例2
输入:"div2"
输出:
        <div id="div2" style="background:Red;">
<div id="div3">
<table id="table1">
<tr>
<td>
<div id="div4" style="width:100p
x"></div>
</td>
</tr>
</table>
</div>
</div>


输入输出样例3
输入:"div3"
输出:
                <div id="div3">
<table id="table1">
<tr>
<td>
<div id="div4" style="width:100p
x"></div>
</td>
</tr>
</table>
</div>



输入输出样例4
输入:"table1"
输出:
                        <table id="table1">
<tr>
<td>
<div id="div4" style="width:100p
x"></div>
</td>
</tr>
</table>


调试代码:
目前只实现没有嵌套的匹配--"div4"
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string html = @"
<html>
<body>
<div id=""div1"">
<div id=""div2"" style=""background:Red;"">
<div id=""div3"">
<table id=""table1"">
<tr>
<td>
<div id=""div4"" style=""width:100px""></div>
</td>
</tr>
</table>
</div>
</div>
<div id=""div5"">
<a href=""http://www.csdn.net"">csdn</a>
</div>
</div>
<img src=""http://www.csdn.net/Images/logo_csdn.gif""/>
</body>
</html>";
Console.WriteLine(html);
string[] idList = { "div1", "div2", "div3", "div4", "table1" };

/* TODO : 这里发挥 */
string pattern = @"<([a-z]+)[^>]*\bid=(""|'){0}\2[^>]*></\1>";

foreach (string id in idList)
{
Match match = Regex.Match(html, string.Format(pattern, id),
RegexOptions.Singleline | RegexOptions.IgnoreCase);
Console.WriteLine("--------begin {0}--------", id);
if (match.Success)
Console.WriteLine(match.Value);
else
Console.WriteLine("o(╯□╰)o");
Console.WriteLine("--------end {0}--------", id);
}
Console.ReadKey();
}
}
}


[Quote=输出]
--------begin div1--------
o(╯□╰)o
--------end div1--------
--------begin div2--------
o(╯□╰)o
--------end div2--------
--------begin div3--------
o(╯□╰)o
--------end div3--------
--------begin div4--------
<div id="div4" style="width:100px"></div>
--------end div4--------
--------begin table1--------
o(╯□╰)o
--------end table1--------
[/Quote]
...全文
1524 99 打赏 收藏 转发到动态 举报
写回复
用AI写文章
99 条回复
切换为时间正序
请发表友善的回复…
发表回复
junlong3636 2012-03-27
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 yagebu1983 的回复:]

我感觉用堆栈实现比较好。。。
还得研究一下。。。
[/Quote]呵呵,我也想到用栈,也已经实现了
十一文 2010-06-23
  • 打赏
  • 举报
回复
神奇的400分的帖子!
mjhuangzk 2010-05-20
  • 打赏
  • 举报
回复
正则这个要好好学一下
ylwqhr 2009-12-28
  • 打赏
  • 举报
回复
收藏,学习!~
SQL77 2009-05-30
  • 打赏
  • 举报
回复
狠狠的学正则
小曦子 2009-04-18
  • 打赏
  • 举报
回复
非常不错,学习了。
mofamans 2009-04-18
  • 打赏
  • 举报
回复
学习一下
wmtwywh 2009-04-18
  • 打赏
  • 举报
回复
高手
benbenkui 2009-04-17
  • 打赏
  • 举报
回复
duping9626 2009-04-17
  • 打赏
  • 举报
回复
mark,有时间再来看
-过客- 2009-04-17
  • 打赏
  • 举报
回复
呵呵,确实越考虑越复杂了

基本上正则就是具体问题具体分析,有什么样的需求就写什么样的正则,适用就好
一些不常见的规则,等真正有这种需求的时候再扩展吧,否则只会增加复杂度,降低效率和可维护性


效率一直是正则招人诟病的地方,但这种效率问题很大程度上是因为使用不当导致的

正则本身就是一种有穷状态机,对于一些需求,我们完全可以自己写状态机搞定,只不过抽象程度不会有正则这么高罢了
Rail100 2009-04-17
  • 打赏
  • 举报
回复
学习一个
王集鹄 2009-04-17
  • 打赏
  • 举报
回复
正则表达式执行效率没有直接写程序处理高,但能减少人的工作量,繁琐的事情就交给计算机了,它闲着也是浪费。

汇编写成的程序是最快的,但绝大多数的程序不是汇编写出来的。

计算机的工作量和人的工作量要做一个平衡。

感谢大家参与关注。
Learn-anything 2009-04-17
  • 打赏
  • 举报
回复
学习
hbsoftsmile 2009-04-17
  • 打赏
  • 举报
回复
en
sharpidd 2009-04-16
  • 打赏
  • 举报
回复
正则只会用最简单的.
-过客- 2009-04-16
  • 打赏
  • 举报
回复
完善一:增加了对以下标签类型的支持
        <div id=div5>
<a href="http://www.csdn.net">csdn</a>
</div>


改进一:效率上
1、如果贪婪模式使用得法,会比非贪婪模式快很多,尤其是在数据源较大的情况下;而正则的效率瓶颈,以及效率陷阱,很多时候是由于非贪婪模式使用不当导致的
2、经测试((?!exp).)exp会比[^char]*?exp或[^char]*exp效率高,应该是.NET的NFA引擎做了优化,其它语言中不敢保证

改进二:容错性
将id做了下预处理Regex.Escape(id)),否则输入的id为“abc(def”这类包含正则中需转义的字符时,会抛异常
                Match match = Regex.Match(html, string.Format(pattern, Regex.Escape(id)),
RegexOptions.Singleline | RegexOptions.IgnoreCase);


PS1:目前好像只有.NET支持平衡组和不定长的负向预搜索(?<=\d+)
PS2:固化分组(?>exp)好像也是绝大部分语言所不支持的
-过客- 2009-04-16
  • 打赏
  • 举报
回复
介个,伴水写不出这个正则,骗淫的吧

orain 25楼的正则已基本上满足需求了,完善了一下,做了些优化
            string html = @"
<html>
<body>
<div id=""div1"">
<div id=""div2"" style=""background:Red;"">
<div id=""div3"">
<table id=""table1"">
<tr>
<td>
<div id=""div4"" style=""width:100px""></div>
</td>
</tr>
</table>
</div>
</div>
<div id=div5>
<a href=""http://www.csdn.net"">csdn</a>
</div>
</div>
<img src=""http://www.csdn.net/Images/logo_csdn.gif""/>
</body>
</html>";
Console.WriteLine(html);
string[] idList = { "div1", "div2", "div3", "div4", "table1", "div5", "abc(def" };

/* TODO : 这里发挥 */
string pattern = @"<([a-z]+)(?:(?!id)[^<>])*id=([""']?){0}\2[^>]*>(?>(?<o><\1[^>]*>)|(?<-o></\1>)|(?:(?!</?\1).))*(?(o)(?!))</\1>";

foreach (string id in idList)
{
Match match = Regex.Match(html, string.Format(pattern, Regex.Escape(id)),
RegexOptions.Singleline | RegexOptions.IgnoreCase);
Console.WriteLine("--------begin {0}--------", id);
if (match.Success)
Console.WriteLine(match.Value);
else
Console.WriteLine("o(╯□╰)o");
Console.WriteLine("--------end {0}--------", id);
}
Console.ReadLine();
HSBOY86 2009-04-16
  • 打赏
  • 举报
回复
唉!我今天也要用到正则表达式,不过好像不会用似的,真失败
Jock.Chen 2009-04-16
  • 打赏
  • 举报
回复
学习
加载更多回复(76)

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧