免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 11240 | 回复: 41
打印 上一主题 下一主题

网页抽取正则问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-17 22:50 |只看该作者 |倒序浏览
my $html = "<table><tr><td>aa</td><td>bb</td></tr></table>标记1<table><tr><td>cc</td><td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>";

我有这样一段网页代码,我想得到“标记1”后的td对,即:<td>cc</td><td>dd</td>,并装入数组@td,相当于
@td = ("<td>cc</td>","<td>dd</td>");

我以前都是分两次走,显然很啰嗦:
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;

  4. my $html = "<table><tr><td>aa</td><td>bb</td></tr></table>标记1<table><tr><td>cc</td><td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>";
  5. my ($need) = ($html =~ /标记1(.*?)标记2/i);
  6. my (@td) = ($need =~ /(<td>.*?<\/td>)/ig);
  7. print "@td";
复制代码
有没有办法一步做到?
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;

  4. my $html = "<table><tr><td>aa</td><td>bb</td></tr></table>标记1<table><tr><td>cc</td><td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>";
  5. my @td = ($html =~ /.*?标记1.*?(<td>.*?<\/td>)+/i);
  6. print "@td";
复制代码
尝试这样写,但只得到"<td>dd</td>"。

请精通正则的高手指教。

论坛徽章:
0
2 [报告]
发表于 2010-12-17 22:54 |只看该作者
那为何不用HTML::TreeBuilder 呢?一定要正则?

论坛徽章:
0
3 [报告]
发表于 2010-12-17 22:56 |只看该作者
本帖最后由 x9x9 于 2010-12-17 23:09 编辑

一定要两个标记之间的,如果用正则的话估计谁都得两步走吧?

论坛徽章:
0
4 [报告]
发表于 2010-12-17 22:57 |只看该作者
我已习惯了用正则,有空试试HTML::TreeBuilder 。

我这里只是举个例子,有些时候,数据不是网页,也有类似情况。

论坛徽章:
0
5 [报告]
发表于 2010-12-18 12:13 |只看该作者
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;

  4. my $html = "<table><tr><td>aa</td><td>bb</td></tr></table>标记1<table><tr><td>cc</td><td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>";
  5. my @td = ($html =~ /标记1.*?(<td>.*?<\/td>)(<td>.*?<\/td>)/i);
  6. print "@td";
  7. ;
复制代码
结果 <td>cc</td> <td>dd</td>

论坛徽章:
0
6 [报告]
发表于 2010-12-18 13:24 |只看该作者
回复 5# heut2009


    很强大,学习了。

论坛徽章:
0
7 [报告]
发表于 2010-12-18 13:49 |只看该作者
结果 cc dd
heut2009 发表于 2010-12-18 12:13


你的正则写的和他第一步提取的结果差不多一样长了。
多亏楼主的例子里只有两个<td></td>,否则你的正则要写很长了。

论坛徽章:
0
8 [报告]
发表于 2010-12-18 14:14 |只看该作者
本帖最后由 x9x9 于 2010-12-18 14:15 编辑

用下前后断言应该就可以了~
  1. use strict;
  2. use warnings;

  3. my $html = '<table><tr><td>aa</td><td>bb</td></tr></table>标记1<table><tr><td>cc</td><td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>';
  4. my @td=($html=~m{(?<=标记1).*?((?:<td>.*?</td>)+).*(?=标记2)}i);

  5. print @td;
复制代码

论坛徽章:
0
9 [报告]
发表于 2010-12-18 14:57 |只看该作者
回复 8# x9x9


    正则虽然无所不能,但是效率上想也知道会很低,我一般都用index 和substr ,截取出目标段,然后再匹配。

论坛徽章:
0
10 [报告]
发表于 2010-12-18 15:15 |只看该作者
学习了。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP