怪物perl正则表达式

时间:2010-07-28 20:34:09

标签: regex perl bash

我正在尝试更改这样的字符串:

<a href='../Example/case23.html'><img src='Blablabla.jpg'

对此:

<a href='../Example/case23.html'><img src='<?php imgname('case23'); ?>'

我有这个正则表达式的怪物:

find . -type f | xargs perl -pi -e \
  's/<a href=\'(.\.\.\/Example\/)(case\d\d)(.\.html\'><img src=\')*\'/\1\2\3<\?php imgname\(\'\2\'); \?>\'/'

但它不起作用。事实上,我认为这是Bash的一个问题,可能会很快指出。

r: line 4: syntax error near unexpected token `('
r: line 4: `  's/<a href=\'(.\.\.\/Example\/)(case\d\d)(.\.html\'><img src=\')*\'/\1\2\3<\?php imgname\(\'\2\'); \?>\'/''

但是,如果你想帮助我使用那些很酷的正则表达式!

5 个答案:

答案 0 :(得分:2)

教你如何钓鱼:

s/…/…/

/运算符使用s以外的分隔符,因为/已经出现在表达式中。

s{…}{…}

减少反斜杠引用,更喜欢[.]而不是\.,因为我们稍后会进行shellquote。让我们只为必要或重要的部分保留反斜杠,即数字字符类。

s{<a href='[.][.]/Example/case(\d\d)[.]html'>…

仅捕获变量部分。如果大部分是静态的,则无需稍后重新组合字符串。

s{<a href='[.][.]/Example/case(\d\d)[.]html'><img src='[^']*'}{<a href='../Example/case$1.html'><img src='<?php imgname('case$1'); ?>'}

使用$1代替\1来表示反向引用。 [^']*表示下一个'之前的所有内容。

现在作为Perl -e选项的参数,该程序需要被shellquoted。使用以下帮助程序,您也可以使用别名或shell函数:

> cat `which shellquote`
#!/usr/bin/env perl
use String::ShellQuote qw(shell_quote); undef $/; print shell_quote <>

运行它并粘贴程序体,使用 Ctrl + d 终止输入,您收到:

's{<a href='\''[.][.]/Example/case(\d\d)[.]html'\''><img src='\''[^'\'']*'\''}{<a href='\''../Example/case$1.html'\''><img src='\''<?php imgname('\''case$1'\''); ?>'\''}'

将它与shell管道放在一起。

find . -type f | xargs perl -pi -e 's{<a href='\''[.][.]/Example/case(\d\d)[.]html'\''><img src='\''[^'\'']*'\''}{<a href='\''../Example/case$1.html'\''><img src='\''<?php imgname('\''case$1'\''); ?>'\''}'

答案 1 :(得分:1)

Bash单引号不允许任何转义。

在bash提示下试试这个,你会明白我的意思:

FOO = '\' 富'

将导致它提示您寻找第四个单引号。如果你满意,你会发现FOO的值是

\ FOO

您需要在表达式周围使用双引号。虽然实际上,您的HTML应该首先使用双引号。

答案 2 :(得分:1)

Bash中单引号内的单引号:

set -xv
echo ''"'"''
echo $'\''

答案 3 :(得分:0)

我不会使用单行。将您的Perl代码放在一个脚本中,这样可以更容易地获得正则表达式,而不用担心转义引号等。

我会使用这样的脚本:

#!/usr/bin/perl -pi

use strict;
use warnings;

s{
    ( <a \b [^>]* \b href=['"] [^'"]*/case(\d+)\.html ['"] [^>]* > \s*
      <img \b [^>]* \b src=['"] ) [^'"<] [^'"]*
}{$1<?php imgname('case$2'); ?>}gix;

然后执行以下操作:

find . -type f | xargs fiximgs

- 迈克尔

答案 4 :(得分:0)

如果你安装了mysql软件包,它会附带一个名为replace的命令。

使用replace命令,您可以:

while read line 
do
 X=`echo $line| replace "<a href='../Example/"  ""|replace ".html'><" " "|awk '{print $1}'`
 echo "<a href='../Example/$X.html'><img src='<?php imgname('$X'); ?>'">NewFile   
done < myfile

同样可以用sed完成。 sed s /'my string'/'replace string'/ g .. replace更容易使用特殊字符。