3

我试图将括号内的内容放入 img 标记中 src 属性的值中:

while(<TOCFILE>)
{
    $toc_line = $_;
    $toc_line =~ s/<inlineFig.*?(\.\.\/pics\/ch09_inline99_*?\.jpg)*?<\/inlineFig>/<img src="${1}" alt="" \/\>/g;
    $new_toc_file .= $toc_line;
}

所以我希望在输出中看到这样的标签:

<img src="../pics/ch09_inline99_00" alt="" />

但相反,我得到:

<img src="" alt="" />
4

3 回答 3

12

您的正则表达式中有一个错误,因此该短语永远不会匹配任何内容:

inline99_*?\.jpg
        ^^^ 

\d从您尝试匹配的示例数据来看,我认为您忘记了在明星面前。

您甚至没有要求它匹配,因为您*?在捕获的组之后放置了一个。所以,它只是不匹配任何东西。所以这就是你得到的:什么都没有。

除了:

($PATTERN)*?

只会捕获它匹配的最后一个东西。那可能也不是你想要的。例如:

$_ = 'one two three';
s/(\w+\s*)*/$1/;
print;

打印“三”。

于 2008-12-05T17:19:31.950 回答
3

1)可以使用一些你正在解析的例子。

2)如果在表达式末尾使用“x”,可以在正则表达式中添加空格和注释,使其更易于理解

3)此外,通过分解它,您会注意到 ( ) 内的第二部分内容缺少数字匹配...而不是寻找 0 或多个“_”,并在看到数字时中断,因此不匹配。

while(<TOCFILE>)
{
    $toc_line = $_;
    $toc_line =~ 
      s/                  # replace the follwoing     

         <inlineFig                     # match this text             
         .*?                            # then any characters until the next sequence matches
         (                              # throw the match into $1
            \.\.\/pics\/ch09_inline99_  # ..\pics\cho9_inline99_
            \d*?\.jpg                   # folowed by 0 or more numbers
         )*?                            # keeping doing that until the next sequence matches
         <\/inlineFig>                  # match this text

       /                  # with the follwoing


         <img src="${1}" alt="" \/\>    # some text and the result of $1 above.

       /xg;  # <- the x makes it ignore whitespace and #comments
    $new_toc_file .= $toc_line;
}

4)如前所述,()*?只将最后一个匹配返回到 $1,但如果您的输入只是某种格式,这应该不是问题。

于 2008-12-05T17:53:16.107 回答
1

按照 bart 的建议,修复您的模式,并考虑使用“主题”变量 $_ 而不是将从文件句柄读取的数据显式分配给另一个变量。

#!/usr/bin/perl

use warnings;
use strict;

my $new_toc_file;

{
    # localizing $_ protects any existing value in the global $_
    # you should localize $_ even if you choose to assign it to a variable

    local $_;

    while(<DATA>) { 
        # in the absence of the bind operator =~, s/// operates against $_
        s!<inlineFig.*?(\.\./pics/ch09_inline99_.*?\.jpg)</inlineFig>!<img src="$1" alt="" />!g;
        $new_toc_file .= $_;
    }
}

print $new_toc_file, "\n";

__END__
<inlineFig>../pics/ch09_inline99_00.jpg</inlineFig>
于 2008-12-05T18:04:41.250 回答