为了缩短一些名称,但仍然保持它们的可读性,我想从字符串中删除所有元音,除了第一个和最后一个出现的元音。例如,我希望“Minnesota”变为“Minnsta”。
my $name="Minnesota";
我尝试使用 Perl 的零宽度后视正则表达式语法,如下所示:
$name =~ s/(?<=[aeiou])([^aeiou]*)[aeiou]/$1/ig; # minnst
然而,虽然这正确地处理了第一个元音,但它删除了最后一个元音。 为了解决这个问题,我尝试保留最后一个元音,如下所示:
$name =~ s/(?<=[aeiou])([^aeiou]*)([aeiou])([aeiou][^aeiou]*)$/$1$3/ig; # minnesota
这也不起作用,大概是因为“$”将整个正则表达式锚定到字符串的末尾。
当然,我可以查找第一个元音的位置,反转字符串的其余部分并删除除“第一个”(最后一个)之外的所有元音,然后重新反转并连接字符串,但这不是很好优雅的。我觉得我忽略了零宽度语法的选项之一。
最佳答案
只需为正则表达式指定结束边界条件:(?![^aeiou]*$)
:
use strict;
use warnings;
my @words = qw(Minnesota concatenate strings elegant I feel overlooking options syntax any greatly appreciated);
for (@words) {
my $word = $_;
$word =~ s/(?<=[aeiou])([^aeiou]*)[aeiou](?![^aeiou]*$)/$1/ig;
printf "%-12s -> %s\n", $_, $word;
}
输出:
Minnesota -> Minnsta
concatenate -> conctnte
strings -> strings
elegant -> elgant
I -> I
feel -> feel
overlooking -> ovrlking
options -> optons
syntax -> syntax
any -> any
greatly -> greatly
appreciated -> apprcted
关于regex - Perl 单词拆元音 : removing all vowels except the first and last,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25189812/