2012-06-27 128 views
3

在perl中有很多次,我想在匹配完成另一个替换操作符后用自己替换匹配的字符串。例如,我有一个应用程序,我需要查找带引号的字符串并从中删除空格。这样做的一个方法是:正则表达式中的perl正则表达式

while($str =~ s/"([^"])+"//){ 
    $temp = $1; 
    $temp2 = $temp; 
    $temp =~ s/ /_/g; 
    $str =~ s/$temp2/$temp1/; 
} 

这也似乎是可能的:

$str =~ s/"([^"])+"/replace_spaces($1)/gx; 
sub replace_spaces(){ 
    $word = shift; 
    $word =~ s/ /_/g; 
    return $word; 
} 

是否有这样做,通过正则表达式莫名其妙嵌套在一个正则表达式的正则表达式的纯方式?

+1

是的,我知道这是在编程Perl的巨大的正则表达式章节中讨论,但我不记得了。 – djechlin

回答

2

是的,你可以做到这一点,但在每种情况下,你需要创造新正则表达式。 在这种情况下没有银弹。

您必须使用下划线而不是全部空格来更改空格,只能使用引号内的分隔子字符串。最后一个检查条件是展望未来,然后看看后面的断言,但这些检查并不容易制定。

例如:

$ perl -pe 's/(?<=")(\S+)\s+(?=.*")/$1_/g;' 
a b "c d" e f 
a b "c_d" e f 

但这重新远非完美。这在最简单的情况下起作用。这不是一个解决方案,它只是这个想法的演示。

1

你可以尝试:

$str =~ s{"([^"]+)"}{do{(local$_=$1)=~y/ /_/;$_}}eg; 

或者,为了更好的可读性:

$str =~ s/ 
      "([^"]+)"  # all inside double quotes to $1 
      /do{   # start a do block 
       local $_ = $1; # get a copy from $1 
       y| |_|;  # transliterate ' ' to '_' 
       $_    # return string from block 
       }   # end the do block 
      /xeg; 

问候

RBO