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;
}
通过在正则表达式中以某种方式嵌套正则表达式,是否有一种纯正的正则表达方式?
答案 0 :(得分:3)
对于手头的具体任务,您可以使用Text::ParseWords:
获得更好的服务#!/usr/bin/env perl
use strict; use warnings;
use feature 'say';
use Text::ParseWords;
my $input = q{This is "a t e s t " string. "Hello - world !"};
my @words = shellwords $input;
for my $word ( @words ) {
$word =~ s/ +//g;
say "'$word'";
}
另见How can I split a [character]-delimited string except when inside [character]?
答案 1 :(得分:2)
是的,你可以这样做,但在每种情况下你都需要发明新的正则表达式。 在这种情况下没有银弹。
您必须使用下划线更改空格,但不能更改所有空格,仅限于引号内的分隔子串。你检查的最后一个条件是向前看并查看断言,但这些检查并不那么容易制定。
例如:
$ perl -pe 's/(?<=")(\S+)\s+(?=.*")/$1_/g;'
a b "c d" e f
a b "c_d" e f
但这种情况远非完美。这在最简单的情况下重新运行。它不是解决方案,只是对这个想法的一种表现。
答案 2 :(得分: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