修改和替换字符串中的引用子字符串

时间:2014-09-27 04:36:13

标签: regex string perl replace

我正在从事一个语言翻译项目,并且卡在中间的某个地方。

我的情况是有像

这样的字符串
print "$Hi $There","$Welcome $Aboard"

我希望得到

print "Hi There", "Welcome Aboard" 

即。提取引用的子串,剥离' $'并用新的子串替换原始文件。

我能够提取和更改引用的子串,但是当我尝试在原始子串中替换它们时,它不起作用。为了向您展示示例代码:

#!/usr/bin/perl
use strict;
use warnings;

my $str = "print \"\$Hi \$There\",\"\$Welcome \$Aboard\"";
print "Before:\n$str\n";
my @quoted = $str =~ m/(\".*?\")/g; #Extract all the quoted strings
foreach my $subStr (@quoted)
{
  my $newSubStr = $subStr;
  $newSubStr =~ s/\$//g;    #Remove all the '$'

  $str =~ s/$subStr/$newSubStr/g;   #Replace the string**::Doesn't work**
}
print "After:\n$str\n";

我不知道替换失败的原因。非常感谢帮助。

4 个答案:

答案 0 :(得分:0)

您需要在正则表达式中添加\Q\E。你的代码是这样的:

#!/usr/bin/perl
use strict;
use warnings;

my $str = "print \"\$Hi \$There\",\"\$Welcome \$Aboard\"";
print "Before:\n$str\n";
my @quoted = $str =~ m/(\".*?\")/g; #Extract all the quoted strings
foreach my $subStr (@quoted)
{
  my $newSubStr = $subStr;
  $newSubStr =~ s/\$//g;    #Remove all the '$'

  $str =~ s/\Q$subStr\E/$newSubStr/g;   # Notice the \Q and \E
}
print "After:\n$str\n";

发生的事情是$subStr看起来像这样:"$Hi $There"

我不确定它是否将$Hi$There解释为变量,但它并不像您想要的那样匹配文字字符串。您可以在quotemeta docs中了解\Q\E

答案 1 :(得分:0)

尝试此代码:因为您要提取双引号中的子字符串并在双引号中删除$。您可以尝试下面的代码

<强>代码:

#!/usr/bin/perl    
use strict;
use warnings;

my $str = "print \"\$Hi \$There\",\"\$Welcome \$Aboard\"";
print "Before:\n$str\n";

while($str =~ m/(\"[^\"]*\")/isg) #Extract all the quoted strings
 {
      $str =~ s/\$//isg; # Strip $ from $str
    }
print "After:\n$str\n"; 

Perl One班轮代码:

perl -0777 -lne "if($_ =~ m/\".*?\"/isg) {$_ =~ s/\$//isg; print $_;} else { print $_;}" Inputfile

答案 2 :(得分:0)

\$(?=[^"]*"(?:[^"]*"[^"]*")*[^"]*$)

试试这个。只有在$"之间时才会替换"

参见演示。

http://regex101.com/r/lS5tT3/61

答案 3 :(得分:0)

您当前的问题是因为您没有在正则表达式的LHS中使用quotemeta字面值,因此$等特殊字符不会被转义。

但是,您开始使用错误的工具。

如果您想先使用m//进行匹配,然后使用s///进行替换,则很可能需要使用/e Modifier来使用替换块,以便您可以执行RHS中的代码。

以下是您正在尝试的搜索和替换。请注意,我如何仅为4个变量中的3个创建新值,并且还包括一个双引号之外的变量,以显示它是如何被替换的:

#!/usr/bin/perl
use strict;
use warnings;

my %substitute = (
    '$Hi'     => 'Bye',
    '$There'  => 'Somewhere',
    '$Aboard' => 'Away',
);

my $str = 'print "$Hi $There","$Welcome $Aboard", $Hi';

$str =~ s{(".*?")}{
    (my $quoted = $1) =~ s{(\$\w+)}{
        $substitute{$1} || $1
    }eg;
    $quoted
}eg;

print "$str\n";

输出:

print "Bye Somewhere","$Welcome Away", $Hi

如果您打算解析Perl代码,那么您可能应该使用PPI。您可以查看my answers以获取使用该模块的一些示例。