在Perl中替换字符

3

我正在研究如何将每个单词中的所有元音字母都加倍。例如:

$string="if it rains, cover with umbrella";

这是我写的代码,但是我没有得到正确的输出。

$string=~s/a|e|i|o|u/aa|ee|ii|oo|uu/gi; print $string;

期望输出:iif iit raaiins cooveer wiith uumbreelaa

有人能帮我解决这个问题吗?


2
欢迎来到SO!这是一个非常好的第一篇(大概)帖子!然而,我想说的一件事是包括错误的输出以改进。这将有助于人们识别问题所在。 - kevlar1818
4个回答

8

您的替换中的正则表达式应该可以正常工作,但是,正如您所见,替换字符串是一个简单的字符串,与匹配没有任何关系,除非您在正则表达式中捕获子字符串并在替换字符串中使用它们。

使用字符类来匹配一组字符中的任何一个,比如[aeiuo]

使用括号来“捕获”匹配的一部分,以便您可以在替换字符串中使用它。

my $string = "if it rains, cover with umbrella";

$string =~ s/([aeiuo])/$1$1/g;

print $string;

输出

iif iit raaiins, cooveer wiith uumbreellaa

3
所有匹配项都被捕获在变量$1,$2,...,$9中,所以如果你两次替换$1,它将重复匹配的任何内容,这种情况下它将使元音字母加倍。
$string=~ s/(a|e|i|o|u)/\1\1/gi; 
print $string;

10
在替换字符串中使用\1等是不规范的。请参见关于\1而不是$1的警告。此外,多个长度为一的备选项可以写成字符类[aeiuo] - Borodin

1

如前所述,在这种情况下,以下方法可以解决问题:

s/([aeiuo])/$1$1/ig;    # A => AA

或者你想要

s/([aeiuo])/\L$1$1/ig;  # A => aa

以下是一种适用于任意翻译映射的替代解决方案:
my %map = (
   'a' => 'aa',
   'e' => 'ee',
   'i' => 'ii',
   'o' => 'uu',
   'u' => 'oo',
);

my $pat =
   join '|',
    map quotemeta,
     sort { length($b) <=> length($a) }
      keys(%map);

s/($pat)/$map{$1}/g;

即使您拥有上述功能,仍然可以正常工作。

( 'foo' => 'bar',
  'bar' => 'foo' )

如果您没有类似的需求,可以省略sort行。
( 'foo'  => 'bar',
  'food' => 'baz' )

0

你没有打印出错误的输出结果,但你可以简单地将每个元音字母替换为它的双倍。例如:

$string =~ s/a/aa/g;
$string =~ s/e/ee/g;
$string =~ s/i/ii/g;
$string =~ s/o/oo/g;
$string =~ s/u/uu/g;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接