在Perl中,如何使用`s ///`进行多次替换?

ssr*_*012 0 regex perl

我的意见:

 $brackets = '\left \right \center \right \left \middle';
Run Code Online (Sandbox Code Playgroud)

在上面的字符串中,我需要将每个\left字符串替换为(开括号,将每个字符串替换\right)右括号.

我可以用几种方法替换以获得输出.但是我想知道如何在r修饰符中完成此操作.这是我到目前为止所拥有的

 $brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
Run Code Online (Sandbox Code Playgroud)

我不知道在哪里可以找到我的错误.

Sin*_*nür 6

对于要更换涉及只有两个子这个文字的问题,你应该使用两个单独s///@ Patrick85建议.只有当你有3个或更多这样的替代品时,下面的方法才有意义.在这种情况下,将映射隐藏在散列中将使您的代码更清晰.

使用哈希查找替换:

#!/usr/bin/env perl

use strict;
use warnings;

my %replacement = (
    '\left' => '(',
    '\right' => ')'
);

my $s = '\left \right \center \right \left \middle';
my $t = $s =~ s/( \\ (?: left | right ))/$replacement{$1}/rgx;

print "$s\n$t\n";
Run Code Online (Sandbox Code Playgroud)

尝试将所有内容整合到一行中有很多问题:

$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
Run Code Online (Sandbox Code Playgroud)

很难读懂.而且,不可能概括.如果您需要将N个字符串映射到其替换项,会发生什么?让我们尝试通过添加一些空格来更清楚地写这个:

$brackets =~ s{
    \\
    (left | right)
}{
    $& =~ s/\\left/\(/r &&
    $& =~ s/\\right/\)/gr; 
}gex;
Run Code Online (Sandbox Code Playgroud)

即使这样做了你想要的,你现在已经s///用一个简单的哈希查找替换了一个单独的哈希查找,它s///为你的源字符串中的每个匹配做了两个额外的操作.

对于您显示的示例字符串,此字符串将执行八个附加s///操作.

这是不好的.

  • `x`告诉正则表达式引擎忽略空格(包括换行符).它使格式化模式更容易. (3认同)

Fra*_*345 5

使用两个简单的替换而不是一个复杂的替换:

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

my $brackets = '\left \right \center \right \left \middle';

$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;

print $brackets."\n";
Run Code Online (Sandbox Code Playgroud)

输出:

()\ center)(\ middle

  • 老实说,@ ssr1012,为什么不想这样?这是正确的,显而易见的方法。它比问题中的正则表达式更清晰,代码也更短。为什么存在一条线会打扰您这么大? (2认同)