Chinaunix

标题: 网页抽取正则问题 [打印本页]

作者: iamlimeng    时间: 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>"。

请精通正则的高手指教。
作者: x9x9    时间: 2010-12-17 22:54
那为何不用HTML::TreeBuilder 呢?一定要正则?
作者: x9x9    时间: 2010-12-17 22:56
本帖最后由 x9x9 于 2010-12-17 23:09 编辑

一定要两个标记之间的,如果用正则的话估计谁都得两步走吧?
作者: iamlimeng    时间: 2010-12-17 22:57
我已习惯了用正则,有空试试HTML::TreeBuilder 。

我这里只是举个例子,有些时候,数据不是网页,也有类似情况。
作者: heut2009    时间: 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>
作者: 午夜凋零    时间: 2010-12-18 13:24
回复 5# heut2009


    很强大,学习了。
作者: x9x9    时间: 2010-12-18 13:49
结果 cc dd
heut2009 发表于 2010-12-18 12:13


你的正则写的和他第一步提取的结果差不多一样长了。
多亏楼主的例子里只有两个<td></td>,否则你的正则要写很长了。
作者: x9x9    时间: 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;
复制代码

作者: heut2009    时间: 2010-12-18 14:57
回复 8# x9x9


    正则虽然无所不能,但是效率上想也知道会很低,我一般都用index 和substr ,截取出目标段,然后再匹配。
作者: kingwmj    时间: 2010-12-18 15:15
学习了。。。。
作者: li_000828    时间: 2010-12-18 20:37
  1. #!/usr/bin/perl
  2. 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>";
  3. $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(??{push @a,$1})/g;
  4. print "@a\n";
复制代码

作者: iamlimeng    时间: 2010-12-20 10:55
回复 8# x9x9


    谢谢给出的方案,这个可以匹配需要的数据,但没有分别装入数组,它是一次性将所有需要的数据装入数组的第一个元素,要完成任务,那也还是要分两步走。
作者: iamlimeng    时间: 2010-12-20 11:09
回复 11# li_000828


    非常感谢,很好,很强大,是我想要的答案。
作者: langren868    时间: 2010-12-20 17:14
强大个JJ啊,循环下,ok
作者: toniz    时间: 2010-12-21 10:08
11楼用法很巧妙,不过我认为没多少人能看懂
作者: phoenix_perl    时间: 2010-12-21 10:22
呵呵,献丑读解一下这个正则表达式中的非贪婪模式

/标记1.*?(<td>\w+<\/td>).*?标记2(??{push @a,$1})/g


在正则表达式中的贪婪模式
* 代表0到无限次匹配(优先匹配最多的)
+ 代表1到无限次匹配(优先匹配最多的)
? 代表0带1次匹配(优先匹配最多的)
{n,m}代表n到m次匹配(优先匹配最多的)

在正则表达式中的非贪婪模式
*? 代表0到无限次匹配(优先匹配最少的)
+? 代表1到无限次匹配(优先匹配最少的)
?? 代表0带1次匹配(优先匹配最少的)
{n,m}? 代表n到m次匹配(优先匹配最少的)

我记得默认都是贪婪模式,贪婪模式就是匹配最多符合条件的
而在这些标记后面加上?  就是用非贪婪模式
作者: toniz    时间: 2010-12-21 10:23
本帖最后由 toniz 于 2010-12-21 10:26 编辑

没答到点子上
作者: toniz    时间: 2010-12-21 10:29
提示下,这正则是不会匹配到的。
作者: phoenix_perl    时间: 2010-12-21 10:47
标记2(??{push @a,$1})  
如果前面的出现0或1次(优先0次),将前面捕获1中的内容添加到@a中
捕获1的内容是 (<td>\w+<\/td>) \w+是贪婪匹配,加上后面的 .*?标记2 ?? 限制了捕获1的贪婪范围.
perl中的code竟然能写到正则表达式中...
作者: toniz    时间: 2010-12-21 11:05
继续  还不是重点
作者: 黑色阳光_cu    时间: 2010-12-21 12:51
本帖最后由 黑色阳光_cu 于 2010-12-21 12:53 编辑
  1. 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>";
  2. my @ar = $html =~ m{\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)}xg;
  3. warn "@ar";
复制代码
哥不喜欢 (??{})
作者: x9x9    时间: 2010-12-21 13:39
谁再给解释下11楼的写法,google了半天没有答案。
作者: iamlimeng    时间: 2010-12-21 15:02
回复 21# 黑色阳光_cu


    谢谢黑色阳光,这个正则很强大,就是我想要的正则。
作者: toniz    时间: 2010-12-22 09:11
11楼的原理是巧妙的让正则表达式失败,并不断重新尝试。
当正则表达式引擎在字符串中找到符合下面这段正则规制的内容后
  1. /标记1.*?(<td>\w+<\/td>).*?标记2
复制代码
接下来就是把$1内容存入数组,然后这时候让正则表达式匹配失败。
那么正则表达式引擎就会进行新的尝试。
这样就能匹配到所有的符合条件的内容。
作者: toniz    时间: 2010-12-22 09:13
不过11楼的代码写得很隐晦。下面的正则,同样的道理。至于11楼用上/g,这个完全没有必要。
  1. $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(?{print "$1\n"})(?!)/;
  2. $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(?{print "$1\n"})\1/;
复制代码

作者: 黑色阳光_cu    时间: 2010-12-22 09:42
不过11楼的代码写得很隐晦。下面的正则,同样的道理。至于11楼用上/g,这个完全没有必要。
toniz 发表于 2010-12-22 09:13



   


都没有哥的强大
作者: toniz    时间: 2010-12-22 09:51
能够写出11楼那样的正则,证明对正则表达式内部工作原理很了解。他那个正则的效率要比你的高太多。
作者: 黑色阳光_cu    时间: 2010-12-22 09:53
能够写出11楼那样的正则,证明对正则表达式内部工作原理很了解。他那个正则的效率要比你的高太多。
toniz 发表于 2010-12-22 09:51



   
哥不用(?{...})
作者: toniz    时间: 2010-12-22 09:57
只讨论正则,不考虑实际应用。如果实际应该的话,我宁可去用楼主的两个正则来实现。
作者: 黑色阳光_cu    时间: 2010-12-22 10:03
本帖最后由 黑色阳光_cu 于 2010-12-22 10:05 编辑
  1. #!/bin/env perl
  2. # t2.pl

  3. use strict;
  4. use warnings;

  5. foreach (1 .. 200000)
  6. {
  7.         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>";
  8.         #my @ar = $html =~ m{\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)}xg;
  9.         my @a;
  10.         $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(??{push @a,$1})/g;
  11. }
复制代码
$ time perl t2.pl

real    0m3.778s
user    0m0.015s
sys     0m0.015s


-------------------------------------------------- 我是华丽的分界线 -----------------------------------------------------------
  1. #!/bin/env perl
  2. # t.pl

  3. use strict;
  4. use warnings;

  5. foreach (1 .. 200000)
  6. {
  7.         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>";
  8.         my @ar = $html =~ m{\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)}xg;
  9.         #my @a;
  10.         #$html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(??{push @a,$1})/g;
  11. }
复制代码
$ time perl t.pl

real    0m1.271s
user    0m0.031s
sys     0m0.015s

作者: 黑色阳光_cu    时间: 2010-12-22 10:11
本帖最后由 黑色阳光_cu 于 2010-12-22 10:12 编辑
只讨论正则,不考虑实际应用。如果实际应该的话,我宁可去用楼主的两个正则来实现。
toniz 发表于 2010-12-22 09:57





30楼的结果咋解释
作者: toniz    时间: 2010-12-22 10:13
初步看是因为地址复用。。问题在数组  不在正则
你可以看下我之前写的PERL内存管理的帖子。
作者: 黑色阳光_cu    时间: 2010-12-22 10:14
初步看是因为地址复用。。问题在数组  不在正则
你可以看下我之前写的PERL内存管理的帖子。
toniz 发表于 2010-12-22 10:13





那你给个更快的正则吧~
作者: toniz    时间: 2010-12-22 10:24
你直接把字符串加长测试一下试试
作者: 黑色阳光_cu    时间: 2010-12-22 10:31
你直接把字符串加长测试一下试试
toniz 发表于 2010-12-22 10:24


my $html = "<table><tr><td>aa</td><td>bb< /td></tr></table>标记1<table><tr><td>cc</td><td>dd< /td></tr>" . 'a' x 300000 . "</table>标记2<table><tr><td>ee</td><td>ff</td></tr></table>";
   
appleii@r61e /cygdrive/d
$ time perl t2.pl

real    1m2.401s
user    0m0.015s
sys     0m0.015s

appleii@r61e /cygdrive/d
$ time perl t.pl

real    0m51.128s
user    0m0.015s
sys     0m0.015s

作者: toniz    时间: 2010-12-22 10:52
  1. use Data::Dumper;   
  2. use Time::HiRes qw(gettimeofday);



  3. my $html = "" . '<td>asfa</td>' x 300000 . "<table><tr><td>aa</td><td>bb< /td></tr></table>标记1<table><tr><td>cc</td>" . '<td>' x 30000000 . "<td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr>" . 'a' x 30000000 . "</table>";
  4. my ($start_sec, $start_usec) = gettimeofday;
  5. $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(??{push @a,$1})/;
  6. my ($end_sec, $end_usec) = gettimeofday;
  7. my $time_used = ($end_sec - $start_sec) + ($end_usec - $start_usec)/1000000;
  8. printf("time used  : %.3f\n", $time_used);


  9. my ($start_sec, $start_usec) = gettimeofday;
  10. my @ar = $html =~ m{\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)}xg;
  11. my ($end_sec, $end_usec) = gettimeofday;
  12. my $time_used = ($end_sec - $start_sec) + ($end_usec - $start_usec)/1000000;
  13. printf("time used  : %.3f\n", $time_used);


  14. my ($start_sec, $start_usec) = gettimeofday;
  15. $html =~ /标记1.*?(<td>\w+<\/td>).*?标记2(?{push @a,$1})(?!)/;
  16. my ($end_sec, $end_usec) = gettimeofday;
  17. my $time_used = ($end_sec - $start_sec) + ($end_usec - $start_usec)/1000000;
  18. printf("time used  : %.3f\n", $time_used);
复制代码
  1. [etl@dmtest putest]$ perl putest20.pl
  2. time used  : 3.612
  3. time used  : 3.443
  4. time used  : 3.602
复制代码

作者: toniz    时间: 2010-12-22 10:55
  1. Matching REx "标记1.*?(<td>\w+</td>).*?标记2(??{push @a,$1})" against "标记1<table><tr><td>cc</td><td>dd< /td></tr></table>标记2<ta..."
  2.   Setting an EVAL scope, savestack=17
  3.   47 <able>> <标记1<t>    |  1:  EXACT <标记1>
  4.   52 <标记1> <<table>>    |  4:  MINMOD
  5.   52 <标记1> <<table>>    |  5:  STAR
  6.   Setting an EVAL scope, savestack=17
  7.   52 <标记1> <<table>>    |  7:    OPEN1
  8.   52 <标记1> <<table>>    |  9:    EXACT <<td>>
  9.                               failed...
  10.                            REG_ANY can match 7 times out of 7...
  11.   59 <able>> <<tr><td>    |  7:    OPEN1
  12.   59 <able>> <<tr><td>    |  9:    EXACT <<td>>
  13.                               failed...
  14.                            REG_ANY can match 4 times out of 4...
  15.   63 <><tr>> <<td>cc<>    |  7:    OPEN1
  16.   63 <><tr>> <<td>cc<>    |  9:    EXACT <<td>>
  17.   67 <><td>> <cc</td>>    | 11:    PLUS
  18.                            ALNUM can match 2 times out of 2147483647...
  19.   Setting an EVAL scope, savestack=17
  20.   69 <td>cc> <</td><t>    | 13:      EXACT <</td>>
  21.   74 <</td>> <<td>dd<>    | 16:      CLOSE1
  22.   74 <</td>> <<td>dd<>    | 18:      MINMOD
  23.   74 <</td>> <<td>dd<>    | 19:      STAR
  24.   Setting an EVAL scope, savestack=17
  25.                            REG_ANY can match 25 times out of 25...
  26.   99 <able>> <标记2<t>    | 21:        EXACT <标记2>
  27. 104 <标记2> <<table>>    | 24:        LOGICAL[2]
  28. 104 <标记2> <<table>>    | 25:        EVAL
  29.   re_eval 0x9ba5128
  30. Compiling REx `1'
  31. size 3 Got 28 bytes for offset annotations.
  32. first at 1
  33.    1: EXACT <1>(3)
  34.    3: END(0)
  35. anchored "1" at 0 (checking anchored isall) minlen 1
  36. Offsets: [3]
  37.         1[1] 0[0] 2[0]
  38. Entering embedded "1"
  39.   Setting an EVAL scope, savestack=27
  40. 104 <标记2> <<table>>    |  1:          EXACT <1>
  41.                                     failed...
  42. Freeing REx: `"1"'
  43.      restoring \1 to 63(63)..74
  44.                                   failed...
  45.                                 failed...
  46.                               failed...
  47.                            REG_ANY can match 6 times out of 6...
  48.   69 <td>cc> <</td><t>    |  7:    OPEN1
  49.   69 <td>cc> <</td><t>    |  9:    EXACT <<td>>
  50.                               failed...
  51.                            REG_ANY can match 5 times out of 5...
  52.   74 <</td>> <<td>dd<>    |  7:    OPEN1
  53.   74 <</td>> <<td>dd<>    |  9:    EXACT <<td>>
  54.   78 <><td>> <dd< /td>    | 11:    PLUS
  55.                            ALNUM can match 2 times out of 2147483647...
  56.   Setting an EVAL scope, savestack=17
  57.   80 <td>dd> << /td><>    | 13:      EXACT <</td>>
  58.                                 failed...
  59.                               failed...
  60.                            REG_ANY can match 6 times out of 6...
  61.   80 <td>dd> << /td><>    |  7:    OPEN1
  62.   80 <td>dd> << /td><>    |  9:    EXACT <<td>>
  63.                               failed...
  64.                            REG_ANY can match 6 times out of 6...
  65.   86 < /td>> <</tr></>    |  7:    OPEN1
  66.   86 < /td>> <</tr></>    |  9:    EXACT <<td>>
  67.                               failed...
  68.                            REG_ANY can match 5 times out of 5...
  69.   91 <</tr>> <</table>    |  7:    OPEN1
  70.   91 <</tr>> <</table>    |  9:    EXACT <<td>>
  71.                               failed...
  72.                            REG_ANY can match 13 times out of 13...
  73. 104 <标记2> <<table>>    |  7:    OPEN1
  74. 104 <标记2> <<table>>    |  9:    EXACT <<td>>
  75.                               failed...
  76.                            REG_ANY can match 7 times out of 7...
  77. 111 <able>> <<tr><td>    |  7:    OPEN1
  78. 111 <able>> <<tr><td>    |  9:    EXACT <<td>>
  79.                               failed...
  80.                            REG_ANY can match 4 times out of 4...
  81. 115 <><tr>> <<td>ee<>    |  7:    OPEN1
  82. 115 <><tr>> <<td>ee<>    |  9:    EXACT <<td>>
  83. 119 <><td>> <ee</td>>    | 11:    PLUS
  84.                            ALNUM can match 2 times out of 2147483647...
  85.   Setting an EVAL scope, savestack=17
  86. 121 <td>ee> <</td><t>    | 13:      EXACT <</td>>
  87. 126 <</td>> <<td>ff<>    | 16:      CLOSE1
  88. 126 <</td>> <<td>ff<>    | 18:      MINMOD
  89. 126 <</td>> <<td>ff<>    | 19:      STAR
  90.   Setting an EVAL scope, savestack=17
  91.                                 failed...
  92.                               failed...
  93.                            REG_ANY can match 6 times out of 6...
  94. 121 <td>ee> <</td><t>    |  7:    OPEN1
  95. 121 <td>ee> <</td><t>    |  9:    EXACT <<td>>
  96.                               failed...
  97.                            REG_ANY can match 5 times out of 5...
  98. 126 <</td>> <<td>ff<>    |  7:    OPEN1
  99. 126 <</td>> <<td>ff<>    |  9:    EXACT <<td>>
  100. 130 <><td>> <ff</td>>    | 11:    PLUS
  101.                            ALNUM can match 2 times out of 2147483647...
  102.   Setting an EVAL scope, savestack=17
  103. 132 <td>ff> <</td></>    | 13:      EXACT <</td>>
  104. 137 <</td>> <</tr></>    | 16:      CLOSE1
  105. 137 <</td>> <</tr></>    | 18:      MINMOD
  106. 137 <</td>> <</tr></>    | 19:      STAR
  107.   Setting an EVAL scope, savestack=17
  108.                                 failed...
  109.                               failed...
  110.                            REG_ANY can match 6 times out of 6...
  111. 132 <td>ff> <</td></>    |  7:    OPEN1
  112. 132 <td>ff> <</td></>    |  9:    EXACT <<td>>
  113.                               failed...
  114.                            REG_ANY can match 5 times out of 5...
  115. 137 <</td>> <</tr></>    |  7:    OPEN1
  116. 137 <</td>> <</tr></>    |  9:    EXACT <<td>>
  117.                               failed...
  118.                            REG_ANY can match 5 times out of 5...
  119. 142 <</tr>> <</table>    |  7:    OPEN1
  120. 142 <</tr>> <</table>    |  9:    EXACT <<td>>
  121.                               failed...
  122.                             failed...
  123. Match failed
  124. Freeing REx: `"\261\352\274\3071.*?(<td>\\w+</td>).*?\261\352\274\3072(??{"......'
复制代码

作者: toniz    时间: 2010-12-22 10:55
  1. Matching REx "\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)" against "<table><tr><td>aa</td><td>bb< /td></tr></table>标记1<table><..."
  2.   Setting an EVAL scope, savestack=5
  3.    0 <> <<table><tr><>    |  1:  GPOS
  4.    0 <> <<table><tr><>    |  2:  LOGICAL[1]
  5.    0 <> <<table><tr><>    |  3:  IFMATCH[-0]
  6.    0 <> <<table><tr><>    |  5:    BOL
  7.    0 <> <<table><tr><>    |  6:    SUCCEED
  8.                               could match...
  9.    0 <> <<table><tr><>    |  8:  IFTHEN
  10.    0 <> <<table><tr><>    | 10:  MINMOD
  11.    0 <> <<table><tr><>    | 11:  STAR
  12.   Setting an EVAL scope, savestack=5
  13.                            REG_ANY can match 47 times out of 47...
  14.   47 <able>> <标记1<t>    | 13:    EXACT <标记1>
  15.   52 <标记1> <<table>>    | 19:    MINMOD
  16.   52 <标记1> <<table>>    | 20:    STAR
  17.   Setting an EVAL scope, savestack=5
  18.   52 <标记1> <<table>>    | 22:      OPEN1
  19.   52 <标记1> <<table>>    | 24:      EXACT <<td>>
  20.                                 failed...
  21.                            REG_ANY can match 7 times out of 7...
  22.   59 <able>> <<tr><td>    | 22:      OPEN1
  23.   59 <able>> <<tr><td>    | 24:      EXACT <<td>>
  24.                                 failed...
  25.                            REG_ANY can match 4 times out of 4...
  26.   63 <><tr>> <<td>cc<>    | 22:      OPEN1
  27.   63 <><tr>> <<td>cc<>    | 24:      EXACT <<td>>
  28.   67 <><td>> <cc</td>>    | 26:      PLUS
  29.                            ALNUM can match 2 times out of 2147483647...
  30.   Setting an EVAL scope, savestack=5
  31.   69 <td>cc> <</td><t>    | 28:        EXACT <</td>>
  32.   74 <</td>> <<td>dd<>    | 31:        CLOSE1
  33.   74 <</td>> <<td>dd<>    | 33:        IFMATCH[-0]
  34.   74 <</td>> <<td>dd<>    | 35:          MINMOD
  35.   74 <</td>> <<td>dd<>    | 36:          STAR
  36.   Setting an EVAL scope, savestack=5
  37.                            REG_ANY can match 24 times out of 24...
  38.   98 <able>> <标记2<t>    | 38:            EXACT <标记2>
  39. 103 <标记2> <<table>>    | 41:            SUCCEED
  40.                                       could match...
  41.   74 <</td>> <<td>dd<>    | 43:        END
  42. Match successful!
  43. Matching REx "\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)" against "<td>dd</td></tr></table>标记2<table><tr><td>ee</td><td>ff</t..."
  44.   Setting an EVAL scope, savestack=5
  45.   74 <</td>> <<td>dd<>    |  1:  GPOS
  46.   74 <</td>> <<td>dd<>    |  2:  LOGICAL[1]
  47.   74 <</td>> <<td>dd<>    |  3:  IFMATCH[-0]
  48.   74 <</td>> <<td>dd<>    |  5:    BOL
  49.                               failed...
  50.   74 <</td>> <<td>dd<>    |  8:  IFTHEN
  51.   74 <</td>> <<td>dd<>    | 19:  MINMOD
  52.   74 <</td>> <<td>dd<>    | 20:  STAR
  53.   Setting an EVAL scope, savestack=5
  54.   74 <</td>> <<td>dd<>    | 22:    OPEN1
  55.   74 <</td>> <<td>dd<>    | 24:    EXACT <<td>>
  56.   78 <><td>> <dd</td>>    | 26:    PLUS
  57.                            ALNUM can match 2 times out of 2147483647...
  58.   Setting an EVAL scope, savestack=5
  59.   80 <td>dd> <</td></>    | 28:      EXACT <</td>>
  60.   85 <</td>> <</tr></>    | 31:      CLOSE1
  61.   85 <</td>> <</tr></>    | 33:      IFMATCH[-0]
  62.   85 <</td>> <</tr></>    | 35:        MINMOD
  63.   85 <</td>> <</tr></>    | 36:        STAR
  64.   Setting an EVAL scope, savestack=5
  65.                            REG_ANY can match 13 times out of 13...
  66.   98 <able>> <标记2<t>    | 38:          EXACT <标记2>
  67. 103 <标记2> <<table>>    | 41:          SUCCEED
  68.                                     could match...
  69.   85 <</td>> <</tr></>    | 43:      END
  70. Match successful!
  71. Matching REx "\G(?(?=^).*?标记1).*?(<td>\w+</td>)(?=.*?标记2)" against "</tr></table>标记2<table><tr><td>ee</td><td>ff</td></tr></ta..."
  72.   Setting an EVAL scope, savestack=5
  73.   85 <</td>> <</tr></>    |  1:  GPOS
  74.   85 <</td>> <</tr></>    |  2:  LOGICAL[1]
  75.   85 <</td>> <</tr></>    |  3:  IFMATCH[-0]
  76.   85 <</td>> <</tr></>    |  5:    BOL
  77.                               failed...
  78.   85 <</td>> <</tr></>    |  8:  IFTHEN
  79.   85 <</td>> <</tr></>    | 19:  MINMOD
  80.   85 <</td>> <</tr></>    | 20:  STAR
  81.   Setting an EVAL scope, savestack=5
  82.   85 <</td>> <</tr></>    | 22:    OPEN1
  83.   85 <</td>> <</tr></>    | 24:    EXACT <<td>>
  84.                               failed...
  85.                            REG_ANY can match 5 times out of 5...
  86.   90 <</tr>> <</table>    | 22:    OPEN1
  87.   90 <</tr>> <</table>    | 24:    EXACT <<td>>
  88.                               failed...
  89.                            REG_ANY can match 13 times out of 13...
  90. 103 <标记2> <<table>>    | 22:    OPEN1
  91. 103 <标记2> <<table>>    | 24:    EXACT <<td>>
  92.                               failed...
  93.                            REG_ANY can match 7 times out of 7...
  94. 110 <able>> <<tr><td>    | 22:    OPEN1
  95. 110 <able>> <<tr><td>    | 24:    EXACT <<td>>
  96.                               failed...
  97.                            REG_ANY can match 4 times out of 4...
  98. 114 <><tr>> <<td>ee<>    | 22:    OPEN1
  99. 114 <><tr>> <<td>ee<>    | 24:    EXACT <<td>>
  100. 118 <><td>> <ee</td>>    | 26:    PLUS
  101.                            ALNUM can match 2 times out of 2147483647...
  102.   Setting an EVAL scope, savestack=5
  103. 120 <td>ee> <</td><t>    | 28:      EXACT <</td>>
  104. 125 <</td>> <<td>ff<>    | 31:      CLOSE1
  105. 125 <</td>> <<td>ff<>    | 33:      IFMATCH[-0]
  106. 125 <</td>> <<td>ff<>    | 35:        MINMOD
  107. 125 <</td>> <<td>ff<>    | 36:        STAR
  108.   Setting an EVAL scope, savestack=5
  109.                                   failed...
  110.                                 failed...
  111.                               failed...
  112.                            REG_ANY can match 6 times out of 6...
  113. 120 <td>ee> <</td><t>    | 22:    OPEN1
  114. 120 <td>ee> <</td><t>    | 24:    EXACT <<td>>
  115.                               failed...
  116.                            REG_ANY can match 5 times out of 5...
  117. 125 <</td>> <<td>ff<>    | 22:    OPEN1
  118. 125 <</td>> <<td>ff<>    | 24:    EXACT <<td>>
  119. 129 <><td>> <ff</td>>    | 26:    PLUS
  120.                            ALNUM can match 2 times out of 2147483647...
  121.   Setting an EVAL scope, savestack=5
  122. 131 <td>ff> <</td></>    | 28:      EXACT <</td>>
  123. 136 <</td>> <</tr></>    | 31:      CLOSE1
  124. 136 <</td>> <</tr></>    | 33:      IFMATCH[-0]
  125. 136 <</td>> <</tr></>    | 35:        MINMOD
  126. 136 <</td>> <</tr></>    | 36:        STAR
  127.   Setting an EVAL scope, savestack=5
  128.                                   failed...
  129.                                 failed...
  130.                               failed...
  131.                            REG_ANY can match 6 times out of 6...
  132. 131 <td>ff> <</td></>    | 22:    OPEN1
  133. 131 <td>ff> <</td></>    | 24:    EXACT <<td>>
  134.                               failed...
  135.                            REG_ANY can match 5 times out of 5...
  136. 136 <</td>> <</tr></>    | 22:    OPEN1
  137. 136 <</td>> <</tr></>    | 24:    EXACT <<td>>
  138.                               failed...
  139.                            REG_ANY can match 5 times out of 5...
  140. 141 <</tr>> <</table>    | 22:    OPEN1
  141. 141 <</tr>> <</table>    | 24:    EXACT <<td>>
  142.                               failed...
  143.                             failed...
  144. Match failed
  145. Freeing REx: `"\\G(?(?=^).*?\261\352\274\3071).*?(<td>\\w+</td>)(?=.*?\261"......'
  146. [etl@dmtest putest]$
复制代码

作者: toniz    时间: 2010-12-22 11:00
照正则的匹配来看  是11楼的匹配次数少   可以时间运行是你的快  这个啥原因呢   额。。
作者: 黑色阳光_cu    时间: 2010-12-22 11:10
本帖最后由 黑色阳光_cu 于 2010-12-22 11:14 编辑
照正则的匹配来看  是11楼的匹配次数少   可以时间运行是你的快  这个啥原因呢   额。。
toniz 发表于 2010-12-22 11:00



所以我说都没有我的强大哇
作者: toniz    时间: 2010-12-22 11:47
对  确实你的强大   \G这个用得淫荡。
作者: hq8318    时间: 2010-12-24 16:52
未用过perl,在学PHP




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2