求一正则表达式

maojun1980 2009-05-04 05:55:29
<tr bgcolor="#FFFF99" onmouseover="this.bgColor='#FFCCCC'" onmouseout="this.bgColor='#FFFF99'">
<td width="108" height="25">
<a href="/url.htm?u=http://www.123.com/" target="_blank">测试测试</a>
</td>
<td width="108">
121.12.105.213
</td>
<td width="180">
2009年 5月3日 晚上11点59分
</td>
<td width="84" align="center">
测试测试
</td>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<a href="/url.htm?u=http://www.123.com/" target="_blank">测试测试</a>
</td>
</tr>
</table>
</td>
<td width="108">
测试测试
</td>
<td width="68" align="center">
<a href="/url.htm?u=http://www.123.com/" target="_blank">点击查看</a>
</td>
</tr>
...全文
158 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jamy2219 2009-05-05
  • 打赏
  • 举报
回复
学习
我姓区不姓区 2009-05-04
  • 打赏
  • 举报
回复
有过客的那段研究代码,此贴可以成为正则的教学贴了
个人觉得写正则最关键的还是弄清楚需求
LemIST 2009-05-04
  • 打赏
  • 举报
回复
(? <=\ <tr).*?(?=\tr\>)
-过客- 2009-05-04
  • 打赏
  • 举报
回复
那个帖子结的好快。。。

这种有嵌套的需求用正则实现,就一定要用到平衡组了,这没什么好说的
但是因为数据源比较大,性能成为问题的时候,就要考虑到正则的优化了
先给出优化后的代码,楼主所给例子加了1100个,在我的机器上执行时间平均 340ms

using (StreamWriter sw = new StreamWriter(@"G:\正则学习\test.txt", true, Encoding.Default))
{
for (int i = 0; i < 1100; i++)
{
sw.WriteLine(yourStr);
sw.WriteLine(DateTime.Now.ToString());
sw.WriteLine();
}
}
Stopwatch sWatch = new Stopwatch();
sWatch.Start();
Regex reg = new Regex(@"<tr(?>(?:(?!onmouseover).)*)onmouseover=""(?>[^""]*)""(?>(?:(?!onmouseout).)*)onmouseout=""(?>[^""]*)""[^>]*>(?>(?:<tr(?>[^>]*)>(?<o>)|</tr>(?<-o>)|(?!</?tr).)*)(?(o)(?!))</tr>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
string src = string.Empty;
using (StreamReader sr = new StreamReader(@"G:\正则学习\test.txt", Encoding.Default))
{
src = sr.ReadToEnd();
}
using (StreamWriter sw = new StreamWriter(@"G:\正则学习\result.txt", true, Encoding.Default))
{
MatchCollection mc = reg.Matches(src);
foreach (Match m in mc)
{
sw.WriteLine(m.Value);
}
}
sWatch.Stop();
richTextBox2.Text += "Done...\n";
richTextBox2.Text += sWatch.ElapsedMilliseconds.ToString() + " ms";


当性能成为不得不考虑的问题的时候,C#中的正则性能优化从几方面考虑:
1、在频繁调用的方法或是循环中,一定不能用静态方法,而要显式的创建Regex对象
原因是静态方法会临时创建一个Regex对象,用它来调用请求的方法,然后弃用这个对象。而静态方法每次调用,都必须重新检查正则表达式,所以存在效率缺陷。
虽然默认情况下,.NET Framework做了缓存处理,但默认只缓存15个正则表达式,尽管可以通过
Regex.CacheSize = 123;
来调整,但这并不是解决效率问题的根本方法。
2、如果正则需要在循环中调用,且循环次数比较多,正则要先在循环体外预编译,RegexOptions.Compiled 。
预编译会延长编译时间,占用更多的内存,但会加速匹配过程。一般在数据源较大、正则复杂、频繁调用、循环中使用时,可以考虑进行预编译。
当然,在多处调用,且调用频繁的情况下,可以考虑封装到assembly中。
3、在数据源较大时,尽量不要使用非贪婪模式
非贪婪模式(exp)*?以及量词的嵌套使用不当,会造成无限循环回溯,通常是正则效率陷阱的根源,尽量使用排除型字符组[^…]和否定的正向预搜索(?!exp)结合贪婪模式来实现。
4、匹配失败不需要回溯的子表达式,用固化分组(?>…)加速失败过程,同时避免回溯。
5、在循环中使用,当捕获组没有必须使用的理由时,使用非捕获组代替
无意义的捕获组,会占用内存,降低效率

PS:补充了点内容
我姓区不姓区 2009-05-04
  • 打赏
  • 举报
回复

@"<tr[^>]*onmouseover=""[^""]*""[^>]*onmouseout=""[^""]*""[^>]*>.*</tr>"


根据楼主的要求,这个正则可以解决了
阿牛138588 2009-05-04
  • 打赏
  • 举报
回复
(?<=\<tr).*?(?=\tr\>)
我姓区不姓区 2009-05-04
  • 打赏
  • 举报
回复

//str为你的html
foreach (Match match in Regex.Matches(str, @"<tr.*?onmouseover=""this.bgColor='#FFCCCC'"" onmouseout=""this.bgColor='#FFFF99'""[^>]*>((?><tr[^>]*>(?<o>)|</tr>(?<-o>)|[\s\S])*)(?(o)(?!))</tr>"))
{
Console.WriteLine(match.Value);
}
maojun1980 2009-05-04
  • 打赏
  • 举报
回复
就是在HTML 中 取出这样的一行
不好意思 忘记说了。。。
蓝海D鱼 2009-05-04
  • 打赏
  • 举报
回复
正则表达式 作什么, 怎么不说 要 取那些 字符串?

110,536

社区成员

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

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

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