免费注册 查看新帖 |

Chinaunix

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

求一个自动循环替换的正则表达式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-09 10:15 |只看该作者 |倒序浏览
现在要替换文件中所有满足条件的字符串,
替换的值需要 根据 满足条件的字符串查找 文件中查找另一个该串,
举例如下:
以下加粗部分需要被替换(正则表达式: <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>

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

论坛徽章:
0
2 [报告]
发表于 2008-12-09 10:16 |只看该作者
不知道这种替换单用正则表达式能否实现, 是不是需要写perl代码

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
3 [报告]
发表于 2008-12-09 10:57 |只看该作者

  1. 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
  2. <TD ALIGN=CENTER VALIGN=CENTER>
  3. 'SDR'
  4. </TD>
  5. <TD ALIGN=CENTER VALIGN=CENTER>
  6. 0
  7. </TD>
  8. <TD ALIGN=CENTER VALIGN=CENTER>
  9. 345345
  10. </TD>
  11. ...
  12. <A NAME = "linktab0"></A>
  13. <TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
  14. <TR>
  15. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
  16. <B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
  17. </TR>
  18. <TR>
  19. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
  20. <FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>'SDR'</FONT></TD>
  21. </TR>
  22. </TABLE>
  23. <A NAME = "linktab1"></A>
  24. <TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
  25. <TR>
  26. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
  27. <B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
  28. </TR>
  29. <TR>
  30. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
  31. <FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>0</FONT></TD>
  32. </TR>
  33. </TABLE>
  34. <A NAME = "linktab-2"></A>
  35. <TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
  36. <TR>
  37. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
  38. <B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
  39. </TR>
  40. <TR>
  41. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
  42. <FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>345345</FONT></TD>
  43. </TR>
  44. </TABLE>

复制代码

论坛徽章:
0
4 [报告]
发表于 2008-12-09 11:31 |只看该作者
my $data = join '', <DATA>;
$data =~ s{#(linktab.*?)>}[($data =~ m|<A NAME = "$1">.*?<FONT .*?>.*?</FONT>.*?<FONT .*?>(.*?)</FONT>|s) ? $1 . '>' : '']sge;

论坛徽章:
0
5 [报告]
发表于 2008-12-09 22:25 |只看该作者

回复 #3 ynchnluiti 的帖子

多谢, 问题是帮我解决了,

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

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

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
6 [报告]
发表于 2008-12-10 00:19 |只看该作者
原帖由 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[^>]*>([^<]*)) 和其中的([^<]*)

论坛徽章:
0
7 [报告]
发表于 2008-12-10 14:33 |只看该作者
原帖由 ynchnluiti 于 2008-12-10 00:19 发表

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




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


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


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


谢谢。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
8 [报告]
发表于 2008-12-10 19:17 |只看该作者
原帖由 chensanxing 于 2008-12-10 14:33 发表

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

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

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

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

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

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

论坛徽章:
0
9 [报告]
发表于 2008-12-10 23:15 |只看该作者

回复 #8 ynchnluiti 的帖子

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  事实上 只是第四个 () 的内容,

为什么呢?

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
10 [报告]
发表于 2008-12-11 00:32 |只看该作者
原帖由 chensanxing 于 2008-12-10 23:15 发表
s{x}{y} => s/x/y/。是替换第一个{}中的内容。

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

说的不明白 。最好自己动手测试一下。
  1. 你说的对,就是用$4——([^<]*)——的内容替换$1——(<A HREF=#([^>]*).*?</A>)——的内容。
  2. $2, $3用来定位,及保存不用替换的内容。
  3. 以linktab0为例。要实现:
  4. <A HREF=#linktab0><IMG src=link.jpeg border=0></A>
  5. 替换成
  6. 'SDR'
复制代码
  1. 对于正则:(<A HREF=#([^>]*).*?</A>)(.*?"\2".*?</TR>\s*<TR>\s*<TD.*?<FONT[^>]*>([^<]*))
  2. $1=<A HREF=#linktab0><IMG src=link.jpeg border=0></A>
  3. $2=linktab0
  4. $3=
  5. </TD>
  6. <TD ALIGN=CENTER VALIGN=CENTER>
  7. <A HREF=#linktab1><IMG src=link.jpeg border=0></A>
  8. </TD>
  9. <TD ALIGN=CENTER VALIGN=CENTER>
  10. <A HREF=#linktab-2><IMG src=link.jpeg border=0></A>
  11. </TD>
  12. ...
  13. <A NAME = "linktab0"></A>
  14. <TABLE CELLPADING=2 BORDER=2 WIDTH=100%>
  15. <TR>
  16. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff WIDTH=800>
  17. <B><FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>Default</FONT></B></TD>
  18. </TR>
  19. <TR>
  20. <TD ALIGN=LEFT VALIGN=TOP BGCOLOR=#ffffff>
  21. <FONT SIZE=2 COLOR=#000000 FACE='Times New Roman'>'SDR'
  22. "
  23. $4='SDR'
复制代码

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

[ 本帖最后由 ynchnluiti 于 2008-12-11 00:34 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP