管理和记录Perl中的多行替换

时间:2013-02-18 21:31:21

标签: regex perl string-substitution

我最近在Perl最佳实践中了解了\x修饰符,使您能够执行多行缩进和文档等很酷的操作:

$txt =~ m/^                     # anchor at beginning of line
      The\ quick\ (\w+)\ fox    # fox adjective
      \ (\w+)\ over             # fox action verb
      \ the\ (\w+) dog          # dog adjective
      (?:                       # whitespace-trimmed comment:
        \s* \# \s*              #   whitespace and comment token
        (.*?)                   #   captured comment text; non-greedy!
        \s*                     #   any trailing whitespace
      )?                        # this is all optional
      $                         # end of line anchor
     /x;                        # allow whitespace

但是,我无法为查找/替换字符串替换执行等效操作?是否有其他类似的最佳实践应该用于更有效地管理复杂的替代?

编辑以此为例:

$test =~ s/(src\s*=\s*['"]?)(.*?\.(jpg|gif|png))/${1}something$2/sig;

是否有类似的方法可以使用多行/空格来记录,以提高可读性?

非常感谢

4 个答案:

答案 0 :(得分:2)

既然你选择不提供一些不起作用的例子,我会对你可能做错的事情提出一些猜测:

  • 请注意,分隔符(在您的情况下为/)不能出现在正则表达式内的任何注释内,因为它们将指示正则表达式的结束。例如,这个:

    s/foo # this is interesting and/or cool
     /bar/x
    

    无效,因为正则表达式由andor之间的斜杠终止。

  • 请注意,/x对替换字符串不起作用,仅适用于正则表达式本身。例如:

    s/foo/bar # I love the word bar/x
    

    foo替换为bar # I love the word bar

    如果你真的希望能够在replacement-string中添加注释,那么我想你可以使用/e标志来替换表达式。那将让你使用Perl的完整语法。例如:

    s/foo/'bar' # I love the word bar/e
    

以下是 工作的示例:

$test =~
  s/
    # the regex to replace:
    (src\s*=\s*['"]?)      # src=' or src=" (plus optional whitespace)
    (.*?\.(jpg|gif|png))   # the URI of the JPEG or GIF or PNG image
  /
    # the string to replace it with:
    $1 .                   # src=' or src=" (unchanged)
    'something' .          # insert 'something' at the start of the URI
    $2                     # the original URI
  /sige;

答案 1 :(得分:1)

如果我们只是添加/x,我们可以轻松地分解正则表达式部分,包括允许注释。

my $test = '<img src = "http://www.somewhere.com/im/alright/jack/keep/your/hands/off/of/my/stack.gif" />';

$test =~ s/
    ( src \s* = \s* ['"]? ) # a src attribute ...
    ( .*? 
      \. (jpg|gif|png)      # to an image file type, either jpeg, gif or png
    )
    /$1something$2/sigx     # put 'something' in front of it
    ;

如果要拆分替换,则必须使用评估开关(/e)。但匹配部分的多行,工作正常。

请注意,我没有必要将$1分开,因为$1something无论如何都不是有效的标识符,所以我的Perl版本至少不会混淆。

对于我评估的大多数替换,我更喜欢替换分隔符的括号样式:

$test =~ s{
      ( src \s* = \s* ['"]? ) # a src attribute ... '
      ( .*? 
        \. (jpg|gif|png)      # to an image file type, either jpeg, gif or png
      )
    }{
        $1 . 'something' . $2
    }sigxe 
    ;

只是为了让它看起来更像代码。

答案 2 :(得分:0)

$test =~ s/(src\s*=\s*['"]?)    # first group
        (.*?\.(jpg|gif|png))        # second group
        /${1}something$2/sigx;

应该和确实一起工作。当然,你不能在正确的部分使用它,除非你使用像:

这样的东西
$test =~ s/(src\s*=\s*['"]?)    # first group
        (.*?\.(jpg|gif|png))        # second group
        /
        $1              # Get 1st group
        . "something"   # Append ...
        . $2            # Get 2d group
        /sigxe;

答案 3 :(得分:0)

s/foo/bar/

可以写成

s/
   foo     # foo
/
   "bar"   # bar
/xe
  • /x允许模式中的空格
  • /e允许替换表达式中的代码