【问题标题】:Modifying and Replacing Quoted Substrings within a string修改和替换字符串中的带引号的子字符串
【发布时间】:2014-11-22 03:50:37
【问题描述】:

我正在做一个语言翻译项目,但被困在中间的某个地方。

我遇到类似字符串的情况

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";

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

【问题讨论】:

    标签: regex string perl replace


    【解决方案1】:

    您需要在正则表达式中添加\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 的信息。

    【讨论】:

    • 非常感谢。这完美地工作。我不是在解释'$Hi'等...对于将python代码翻译成perl,这是一个粗略的中间解析步骤,我将'$'放在每个单词的前面,然后将其从关键字、字符串等中删除。感谢您的帮助:)
    【解决方案2】:

    试试这个代码:因为你想提取出现在双引号中的子字符串并去掉双引号中的 $。你可以试试下面的代码

    代码:

    #!/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
    

    【讨论】:

      【解决方案3】:
      \$(?=[^"]*"(?:[^"]*"[^"]*")*[^"]*$)
      

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

      查看演示。

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

      【讨论】:

        【解决方案4】:

        您当前的问题是因为您没有在正则表达式的 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 获取使用该模块的一些示例。

        【讨论】:

          猜你喜欢
          • 2023-03-23
          • 2021-12-13
          • 2017-08-21
          • 2019-11-02
          • 1970-01-01
          • 1970-01-01
          • 2012-04-03
          • 2013-07-23
          相关资源
          最近更新 更多