perl regex用于复杂的多行搜索替换

时间:2016-01-20 17:53:35

标签: regex perl replace

我知道关于这个话题有很多问题,但大多数都是相当微不足道的 我无法为我的案子找到解决方案。

我有一组HTML文件,其中包含许多“媒体”项,如下所示 每个都是“段落”,用“\ n \ n”分隔。这是我正在研究的link to a sample file类型。

  <li class="media">
    <div class="media-left">
      <a href="#">
        <img class="media-object" src="4_17-HE-assoc.png" width="250" alt="...">
      </a>
    </div>
    <div class="media-body">
      <h4 class="media-heading">Figure 4.17</h4>
      Association plot for the hair-color eye-color data. Left: marginal table, collapsed over
      gender; right: full table.
    </div>
  </li>

对于每个<img ...>代码,我需要找到src="file"值,并替换上一行的href="#"href="file" class="fancybox。即,这样项目就会像

一样
  <li class="media">
    <div class="media-left">
      <a href="4_17-HE-assoc.png" class="fancybox">
        <img class="media-object" src="4_17-HE-assoc.png" width="250" alt="...">
      </a>
    </div>
    <div class="media-body">
      <h4 class="media-heading">Figure 4.17</h4>
      Association plot for the hair-color eye-color data. Left: marginal table, collapsed over
      gender; right: full table.
    </div>
  </li>

我尝试了以下作为单行,但它没有效果,即它没有进行更改。

perl -pi~ -e '$/ = "";s|<a href="#">\n(\s*<img class="media object") src=(".*png")|<a class="fancybox" href="\2">\n\1 src=\2|ms' ch03.html

有人可以帮忙吗?我会对一个简单的脚本感到满意 用于此并修改Web文件集合的其他类似修改。

编辑:我知道使用HTML::TreeBuilder之类的perl模块可以避免直接解析HTML。如果有人 可以给我一个开始,我可以从那里拿走它。

2 个答案:

答案 0 :(得分:7)

use XML::LibXML qw( );

my $qfn = 'ch03.html';

my $in_qfn = $qfn . "~";
my $out_qfn = $qfn;
rename($qfn, $in_qfn)
   or die("Can't rename \"qfn\": $!\n");

my $parser = XML::LibXML->new();
my $doc = $parser->parse_html_file($in_qfn);

for my $a_node ($doc->findnodes('//a[@href="#"]')) {
   my ($src_node) = $a_node->findnodes('img[1]/@src')
      or next;

   $a_node->setAttribute('href', $src_node->value());
   $a_node->setAttribute('class', 'fancybox');
}
my $html = $doc->toStringHTML();
open(my $fh, '>', $out_qfn)
   or die("Can't create \"$out_qfn\": $!\n");

print($fh $html);

测试:

$ diff -u ch03.html{~,}
--- ch03.html~  2016-01-20 12:41:30.809203040 -0800
+++ ch03.html   2016-01-20 12:41:31.009201042 -0800
@@ -1,7 +1,7 @@
-<div class="contents">
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><body><div class="contents">
 <h1 class="tocpage">Chapter 3: Fitting and Graphing Discrete Distributions</h1>
 <hr class="tocpage">
-
 <div class="row">
   <div class="col-md-6">
     <!-- prelude-inserted  -->
@@ -18,7 +18,7 @@
   <div class="col-md-6">
     <h3>Contents</h3>
     <dl class="chaptoc">
-        <dd>3.1. Introduction to discrete distributions</dd>
+<dd>3.1. Introduction to discrete distributions</dd>
         <dd>3.2. Characteristics of discrete distributions</dd>
         <dd>3.3. Fitting discrete distributions</dd>
         <dd>3.4. Diagnosing discrete distributions: Ord plots</dd>
@@ -27,8 +27,7 @@
         <dd>3.7. Chapter summary</dd>
         <dd>3.8. Lab exercises</dd>
     </dl>
-
-  </div>
+</div>
 </div>

 <!-- more-content -->
@@ -38,11 +37,10 @@
        <h3>Selected figures</h3>
      <a class="btn btn-primary" href="../../Rcode/ch03.R" role="button">view R code</a>
     <ul class="media-list">
-      <li class="media">
+<li class="media">
         <div class="media-left">
-          <a href="#">
-            <img class="media-object" src="saxony-barplot.png" width="250" alt="males in Saxony families">
-          </a>
+          <a href="saxony-barplot.png" class="fancybox">
+            <img class="media-object" src="saxony-barplot.png" width="250" alt="males in Saxony families"></a>
         </div>
         <div class="media-body">
           <h4 class="media-heading">Figure 3.2</h4>
@@ -52,9 +50,8 @@

       <li class="media">
         <div class="media-left">
-          <a href="#">
-            <img class="media-object" src="dbinom2-plot2-1.png" width="250" alt="Binomial distributions">
-          </a>
+          <a href="dbinom2-plot2-1.png" class="fancybox">
+            <img class="media-object" src="dbinom2-plot2-1.png" width="250" alt="Binomial distributions"></a>
         </div>
         <div class="media-body">
           <h4 class="media-heading">Figure 3.9</h4>
@@ -64,9 +61,8 @@

       <li class="media">
         <div class="media-left">
-          <a href="#">
-            <img class="media-object" src="dpois-xyplot2-1.png" width="250" alt="Poisson distributions">
-          </a>
+          <a href="dpois-xyplot2-1.png" class="fancybox">
+            <img class="media-object" src="dpois-xyplot2-1.png" width="250" alt="Poisson distributions"></a>
         </div>
         <div class="media-body">
           <h4 class="media-heading">Figure 3.11</h4>
@@ -76,9 +72,8 @@

       <li class="media">
         <div class="media-left">
-          <a href="#">
-            <img class="media-object" src="Fed0-plots2-1.png" width="250" alt="Hanging rootogram">
-          </a>
+          <a href="Fed0-plots2-1.png" class="fancybox">
+            <img class="media-object" src="Fed0-plots2-1.png" width="250" alt="Hanging rootogram"></a>
         </div>
         <div class="media-body">
           <h4 class="media-heading">Figure 3.15</h4>
@@ -89,9 +84,8 @@

       <li class="media">
         <div class="media-left">
-          <a href="#">
-            <img class="media-object" src="ordplot1-1.png" width="250" alt="Ord plot for the Butterfly data">
-          </a>
+          <a href="ordplot1-1.png" class="fancybox">
+            <img class="media-object" src="ordplot1-1.png" width="250" alt="Ord plot for the Butterfly data"></a>
         </div>
         <div class="media-body">
           <h4 class="media-heading">Figure 3.18</h4>
@@ -100,9 +94,10 @@
         </div>
       </li>

-    </ul> <!-- media-list -->
-  </div> <!-- col-md-12 -->
+    </ul>
+<!-- media-list -->
+</div> <!-- col-md-12 -->
 <!-- footer -->
 </div>  <!-- row -->

-</div>
+</div></body></html>

答案 1 :(得分:1)

我无法抗拒,但写下这个一次性,超级不稳定,发送我解析-html-with-regex-hell sed命令:

sed -i.bak '/<a href="#"/ {
    N
    /\n.*<img class=/ {
        s/^\( *<a href="\).*\(\n.*src="\)\([^"]*\)\(.*\)/\1\3" class="fancybox">\2\3\4/
    }
}' ch03.html

这会查找包含href="#"的行,附加下一行,然后将文件名和fancybox替换为a代码。

区分结果和输入文件:

43c43
<           <a href="#">
---
>           <a href="saxony-barplot.png" class="fancybox">
55c55
<           <a href="#">
---
>           <a href="dbinom2-plot2-1.png" class="fancybox">
67c67
<           <a href="#">
---
>           <a href="dpois-xyplot2-1.png" class="fancybox">
79c79
<           <a href="#">
---
>           <a href="Fed0-plots2-1.png" class="fancybox">