1

我最近一直在学习\xPerl Best Practices 中的修饰符,使您能够做一些很酷的事情,比如多行缩进和文档:

$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

4 回答 4

2

由于您选择不提供不起作用的示例,因此我将对您可能做错的地方提供一些猜测:

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

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

    将不起作用,因为正则表达式由 and 之间的斜杠and终止or

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

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

    将替换foobar # I love the word bar.

    如果您真的希望能够在替换字符串中添加注释,那么我想您可以使用替换表达式,使用/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;
于 2013-02-18T21:50:00.370 回答
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 
    ;

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

于 2013-02-19T00:07:14.187 回答
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;
于 2013-02-18T21:51:36.487 回答
0
s/foo/bar/

可以写成

s/
   foo     # foo
/
   "bar"   # bar
/xe
  • /x在模式中允许空格
  • /e允许替换表达式中的代码
于 2013-02-18T23:05:43.050 回答