求一个自动循环替换的正则表达式

求一个自动循环替换的正则表达式

现在要替换文件中所有满足条件的字符串,
替换的值需要 根据 满足条件的字符串查找 文件中查找另一个该串,
举例如下:
以下加粗部分需要被替换(正则表达式: <A\sHREF=#linktab-?\d+><IMG\ssrc=link.jpeg\sborder=0></A> )
替换的值为 根据#linktab0,#linktab1,#linktab-2查找linktab0,linktab1,linktab-2
之后的表格,将各表格中第二个td的值 取出来分别替换:
    即:
    “<A HREF=#linktab0><IMG src=link.jpeg border=0></A>” 替换成 'SDR'
    “<A HREF=#linktab1><IMG src=link.jpeg border=0></A>” 替换成 0
    “<A HREF=#linktab-2><IMG src=link.jpeg border=0></A>” 替换成 345345  

-----------------------------

<TD ALIGN=CENTER VALIGN=CENTER>
<A HREF=#linktab0><IMG src=link.jpeg border=0></A>
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
<A HREF=#linktab1><IMG src=link.jpeg border=0></A>
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
<A HREF=#linktab-2><IMG src=link.jpeg border=0></A>
</TD>
...
<A NAME = "linktab0"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>'SDR'</FONT></TD>
</TR>
</TABLE>
<A NAME = "linktab1"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>0</FONT></TD>
</TR>
</TABLE>
<A NAME = "linktab-2"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>345345</FONT></TD>
</TR>
</TABLE>

-----------------------------
不知道这种替换单用正则表达式能否实现, 是不是需要写perl代码


[Copy to clipboard] [ - ]
CODE:
perl -e 'local $/; $htm = <>;1 while($htm =~ s{(<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*))}{$4$3}sg);print $htm' 1.html
<TD ALIGN=CENTER VALIGN=CENTER>
'SDR'
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
0
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
345345
</TD>
...
<A NAME = "linktab0"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>'SDR'</FONT></TD>
</TR>
</TABLE>
<A NAME = "linktab1"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>0</FONT></TD>
</TR>
</TABLE>
<A NAME = "linktab-2"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>345345</FONT></TD>
</TR>
</TABLE>

my $data = join '', <DATA>;
$data =~ s{#(linktab.*?)>}[($data =~ m|<A NAME = "$1">.*?<FONT .*?>.*?</FONT>.*?<FONT .*?>(.*?)</FONT>|s) ? $1 . '>' : '']sge;
多谢, 问题是帮我解决了,

但是还有几点不太明白, 希望指点:

1 模式中"\2"  怎么理解
2 整个 模式中  3对 括号,而且有嵌套, 而替换时 用 的 $4$3 代表什么意思?


QUOTE:
原帖由 chensanxing 于 2008-12-9 22:25 发表
多谢, 问题是帮我解决了,

但是还有几点不太明白, 希望指点:

1 模式中"\2"  怎么理解
2 整个 模式中  3对 括号,而且有嵌套, 而替换时 用 的 $4$3 代表什么意思?

1 \2是前面的第二对(按'('出现的顺序)括号捕获的内容,即(<A HREF=#([^>]*).*?</A>) 中([^>]*)捕获的内容
2 共四对括号,$3、$4(按'('出现的顺序)分别是:(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*)) 和其中的([^<]*)


QUOTE:
原帖由 ynchnluiti 于 2008-12-10 00:19 发表

1 \2是前面的第二对(按'('出现的顺序)括号捕获的内容,即(]*).*?) 中([^>]*)捕获的内容
2 共四对括号,$3、$4(按'('出现的顺序)分别是:(.*?"\2".*?\s*\s*([^

对于第二点, 还是不知道如何理解, 难道用 之前 第四和第三个括号中的内容替换 第一个花括号中 匹配的内容?


另外, 那个 while 之前 的 1 表示什么意思?


还是没有弄明白, 麻烦你 再作讲解, 并最好推荐 相关的帖子 或者书籍。


谢谢。


QUOTE:
原帖由 chensanxing 于 2008-12-10 14:33 发表

对于第二点, 还是不知道如何理解, 难道用 之前 第四和第三个括号中的内容替换 第一个花括号中 匹配的内容?
另外, 那个 while 之前 的 1 表示什么意思?

还是没有弄明白, 麻烦你 再作讲解 ...

s{x}{y} => s/x/y/。是替换第一个{}中的内容。

1 while () => while () {;} 没有实际动作。看看大骆驼吧(Perl 语言编程)

QUOTE:
因此我们只写一个 1,这也是一件无聊的事情,不过有时候无聊比没希望好。下面是一些例子,它们又用了一些正则表达式怪兽:

  # 把逗号放在一个整数的合理的位置
  1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/;

s{x}{y} => s/x/y/。是替换第一个{}中的内容。

s{ (<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*)) }{$4$3}
即 s/(<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*))/$4$3/

理论上 用 $4$3 替换 (<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*))  我还是知道的,
但是,实际上 只需要拿 第四个 括号 即 ([^<]*) 来 替换 第一个 括号中的 文本 即 (<A HREF=#([^>]*).*?</A>)  ?

执行这个正则式, 事实上 只替换 了 第一个 {} 中的第一个 () 的内容, $4$3  事实上 只是第四个 () 的内容,

为什么呢?


QUOTE:
原帖由 chensanxing 于 2008-12-10 23:15 发表
s{x}{y} => s/x/y/。是替换第一个{}中的内容。

s{ (]*).*?)(.*?"\2".*?\s*\s*([^

说的不明白 。最好自己动手测试一下。

[Copy to clipboard] [ - ]
CODE:
你说的对,就是用$4——([^<]*)——的内容替换$1——(<A HREF=#([^>]*).*?</A>)——的内容。
$2, $3用来定位,及保存不用替换的内容。
以linktab0为例。要实现:
<A HREF=#linktab0><IMG src=link.jpeg border=0></A>
替换成
'SDR'



[Copy to clipboard] [ - ]
CODE:
对于正则:(<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*))
$1=<A HREF=#linktab0><IMG src=link.jpeg border=0></A>
$2=linktab0
$3=
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
<A HREF=#linktab1><IMG src=link.jpeg border=0></A>
</TD>
<TD ALIGN=CENTER VALIGN=CENTER>
<A HREF=#linktab-2><IMG src=link.jpeg border=0></A>
</TD>
...
<A NAME = "linktab0"></A>
<TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
<B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
</TR>
<TR>
<TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
<FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>'SDR'
"
$4='SDR'

s{...}{$4$3}中的$3是为了保持$3的内容不变。如果写成s{..}{$4}那$3的内容就被替换成空了。