突然想到一个正则问题,应该有难度,来者不拒,lxcnn更是有请。。。

cyhcyhhychyc 2009-12-04 04:49:02
待匹配:固定内容+变化内容1+固定内容+变化内容2+固定内容
实现一个正则,匹配以上形式字符串中的变化的内容(“变化内容1”和“变化内容2”);
要求:能分组取出“变化内容1”和“变化内容2”
大家可以到http://www.laishu.com这个页面来匹配更新列表中的所有分类和书名等变化内容,下面摘下一段:
<td class="homelist1">[玄幻] 《<a class="homelist0" href="http://www.laishu.com/lsinfo/2/2725.htm" target="_blank">侏罗记</a>》<a class="homelist0" href="http://www.laishu.com/book/2/2725/1504826.shtml" title="正文 第337章 战神之翼" target="_blank">正文 第337章 战神之翼</a> </td>

以上哪些变化,哪里不变化应该是一眼就看出来的吧(url和汉字部分是变化的)
注意:这个正则是要求匹配出所有上面那个形式的内容,不是说只能匹配出这个地址的内容而已。把固定内容随便换一下,也能匹配出其中的非固定内容。大家可能会问:这样变化太多了吧,也许一个也匹配不出,我想对于单个匹配过程,首先当然是把固定内容都确定了的,因而就很有特征了。呵呵,有点像万能匹配,不知道能实现不。先搞定的给全分呀
...全文
99 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
-过客- 2009-12-04
  • 打赏
  • 举报
回复
我之前也是理解你的需求的,而已一般来说,也是可以做的

但为了取得最大的通用性,就一定要用非贪婪模式,而不能使用贪婪模式了,这会在很大程序上降低匹配效率,而且在你说的固定的内容换成其它对应关系的内容时,有可能会引入潜在的效率陷阱

string test = GetHtmlCode("http://www.laishu.com/", Encoding.GetEncoding("gb2312"));
Regex reg = new Regex(@"(?is)<td class=""homelist1"">(?<type>.*?)《<a class=""homelist0"" href=""(?<deurl>.*?)"" target=""_blank"">(?<book>.*?)</a>》<a class=""homelist0"" href=""(?<churl>.*?)"" title=""(?<var>.*?)"" target=""_blank"">(?<ch>.*?)</a> </td>");
MatchCollection mc = reg.Matches(test);
foreach (Match m in mc)
{
richTextBox2.Text += m.Groups["type"].Value + "\n";
richTextBox2.Text += m.Groups["deurl"].Value + "\n";
richTextBox2.Text += m.Groups["book"].Value + "\n";
richTextBox2.Text += m.Groups["churl"].Value + "\n";
richTextBox2.Text += m.Groups["var"].Value + "\n";
richTextBox2.Text += m.Groups["ch"].Value + "\n------------\n";
}
richTextBox2.Text += mc.Count + "\n";


由于你说的“固定内容”在不同的匹配中是不同的,所以都可以用变量来表示,每次替换一组这样的变量就是了,但要做转义处理
Regex reg = new Regex("(?is)" + Regex.Escape(str1) + "(?<type>.*?)" + Regex.Escape(str2) + "(?<deurl>.*?)" + Regex.Escape(str3) + "(?<book>.*?)" + Regex.Escape(str4) + "(?<churl>.*?)" + Regex.Escape(str5) + "(?<var>.*?)" + Regex.Escape(str6) + "(?<ch>.*?)" + Regex.Escape(str7));


而事实上,这并不是我所推荐的做法

PS:你写的正则中,{1,1}等价于{1},而这个量词有与没有是一样的,所以完全是多余的

cyhcyhhychyc 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lxcnn 的回复:]
其实按楼主说的,这是一个动态生成正则的过程,那么哪些是变化的,哪些是不变的,你还是要去分析的,如果你把规律分析出来了,那正则也基本上就出来了,所以没必要这样动态写正则

因为正则是根据实际需求量体裁衣的,比如两边不变的内容是“"”,那么中间变化内容的正则就可以写做“[^"]*”;而如果两边不变的内容分别是“ <”和“>”,那么为了获得更好的效率和准确性,中间变化内容的正则就可以写作“[^ <>]*”,这是根据实际需求分析得到的,如果此时中间变化的内容还是写做“[^"]*”,那就可能会得到错误结果了

按楼主的需求,我很想换另一种说法
不变的是知识,变化的是需求,只要掌握了相应的知识,就可以应对随时变化的需求了

或许有些“大道理”之嫌,但事实也基本上是这样的
[/Quote]

[Quote=引用 4 楼 lxcnn 的回复:]
其实按楼主说的,这是一个动态生成正则的过程,那么哪些是变化的,哪些是不变的,你还是要去分析的,如果你把规律分析出来了,那正则也基本上就出来了,所以没必要这样动态写正则

因为正则是根据实际需求量体裁衣的,比如两边不变的内容是“"”,那么中间变化内容的正则就可以写做“[^"]*”;而如果两边不变的内容分别是“ <”和“>”,那么为了获得更好的效率和准确性,中间变化内容的正则就可以写作“[^ <>]*”,这是根据实际需求分析得到的,如果此时中间变化的内容还是写做“[^"]*”,那就可能会得到错误结果了

按楼主的需求,我很想换另一种说法
不变的是知识,变化的是需求,只要掌握了相应的知识,就可以应对随时变化的需求了

或许有些“大道理”之嫌,但事实也基本上是这样的
[/Quote]


谢谢您的教导。不过我想你还没有明白我的意思。
我现在不想写一个具体针对某个特定要匹配的内容的正则,而是要写出针对满足“同一形式”的一类的内容的共用的正则。

同一形式(当然可以延长啦,只要是不变的夹着变的):固定内容+变化内容1+固定内容+变化内容2+固定内容
我见到有人实现过,就是自己想不出来。
我写了一个:
(?is)(<td class=""homelist1"">){1,1}(?<type>.*)( 《<a class=""homelist0"" href=""){1,1}(?<deurl>.*)("" target=""_blank"">){1,1}(?<book>.*)(</a>》<a class=""homelist0"" href=""){1,1}(?<churl>.*)("" title=""){1,1}(?<var>.*)("" target=""_blank"">){1,1}(?<ch>.*)(</a> </td>){1,1}

用来匹配:
<td class="homelist1">[玄幻] 《 <a class="homelist0" href="http://www.laishu.com/lsinfo/2/2725.htm" target="_blank">侏罗记 </a>》 <a class="homelist0" href="http://www.laishu.com/book/2/2725/1504826.shtml" title="正文 第337章 战神之翼" target="_blank">正文 第337章 战神之翼 </a> </td>

在组type里可以取出所有的内容(所有组的内容),而我本意当然是希望它只取出"分类"的内容。其它组却只能取出一个,本来要取出全部一组的。我想实现每个组各自取出其对应的所有匹配内容。
注意:这只是一个特例而已,我可以想你建议的那样用[^<>]来做,但是这就把“固定内容”里的东西用上了, 因而与“固定内容”耦合了,推动了普遍适用性。要知道,实际上可以把变化内容看成黑盒子(里面放除了换行符外的任何东西都行),而固定内容,在某个具体匹配时,它是固定的,也就可以用明文表示出来,只是到匹配另一个字符串时又换了,但是字符的形式是一样的。简单说就是在用的时间实时组合成一个确定的正则。但这个正则不要人去一个个写了,用程序就可以组装成功了。有点像拼接sql语句。
呵呵,不知道老大懂了没有
dai_oath 2009-12-04
  • 打赏
  • 举报
回复
支持过客正则。。嘿嘿
-过客- 2009-12-04
  • 打赏
  • 举报
回复
其实按楼主说的,这是一个动态生成正则的过程,那么哪些是变化的,哪些是不变的,你还是要去分析的,如果你把规律分析出来了,那正则也基本上就出来了,所以没必要这样动态写正则

因为正则是根据实际需求量体裁衣的,比如两边不变的内容是“"”,那么中间变化内容的正则就可以写做“[^"]*”;而如果两边不变的内容分别是“<”和“>”,那么为了获得更好的效率和准确性,中间变化内容的正则就可以写作“[^<>]*”,这是根据实际需求分析得到的,如果此时中间变化的内容还是写做“[^"]*”,那就可能会得到错误结果了

按楼主的需求,我很想换另一种说法
不变的是知识,变化的是需求,只要掌握了相应的知识,就可以应对随时变化的需求了

或许有些“大道理”之嫌,但事实也基本上是这样的
cyhcyhhychyc 2009-12-04
  • 打赏
  • 举报
回复
人在哪里?
nosuchtracter 2009-12-04
  • 打赏
  • 举报
回复
这个网站不河蟹
cyhcyhhychyc 2009-12-04
  • 打赏
  • 举报
回复

62,254

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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