如何删除句子中除了第一个字母的元音之外的所有元音?
Posted
技术标签:
【中文标题】如何删除句子中除了第一个字母的元音之外的所有元音?【英文标题】:How can I remove all vowels in a sentence except for the vowel at the first letter? 【发布时间】:2021-11-11 23:27:30 【问题描述】:这段代码具体有什么问题?我该如何纠正?
$x = "without any vowels after the first letter\n";
foreach $i (@x[1..])
if ($i =~ /[AEIOUaeiou]/)
$x =~ tr/A E I O U a e i o u//d;
print "$x\n";
我尝试[1..]
排除第一个字母。如果它不起作用,我还能如何删除第一个字母?
编辑我编辑了代码,使其在语法上(大部分)正确,以传达他们明显的原始想法,除了尝试索引到在 Perl 中不正确的字符串。 (澄清这是我认为在这个问题中有用的一部分。)
【问题讨论】:
"这段代码有什么特别的问题?" --- 几乎所有的东西 -- 所写的大部分内容都不是有效的 Perl,或者实际上是任何编程语言。如果您想要/需要使用 Perl,我建议您阅读 Perl 教程,以便能够明智地使用该语言。学习基础知识并不需要很长时间。 (而且,我看不出您如何实现对实际问题的回答?) 也许你会发现有用的Modern Perl,Beginning Perl。 请阅读:How to create a Minimal, Reproducible Example, How do I ask a good question? 这是***.com/q/69218900/2766176的副本 @briandfoy 不是——他们想让每个单词中的第一个字符在该问题中不受影响,在这里他们只想留下字符串的第一个字符。其他问题的简单解决方案不在这里。 (另外,这个问题是第一位的,并不比另一个差。) 【参考方案1】:首先,其中大部分不是 Perl,也不是任何编程语言。我建议您首先阅读您选择的 Perl 教程,然后再尝试获取特定问题的解决方案。不过,这里有一个答案,因为这个问题本身就足够引起人们的兴趣。
接下来,在 Perl 中你不能直接索引到一个字符串,所以你不能像这样跳过第一个字符。
当然,您可以将字符串中的第一个字符分开并处理其余字符(删除元音)。正则表达式的一种方法†
use warnings;
use strict;
use feature 'say';
my $str = shift // 'out with ALL vowels after first';
$str =~ s/.\K(.*)/ $1 =~ tr[aeiouAEIOU]dr /e;
say $str; #--> ot wth LL vwls ftr frst
这依赖于/e
修饰符,这使得替换端被评估为代码,因此它在那里运行一个独立的transliteration (tr
),处理捕获的子字符串。
然后我们需要嵌入的tr
/regex 中的/r
modifier,以返回新字符串,而不是更改旧字符串——无论如何,这是不可能的无法更改$1
。
也可以使用tr
的正则表达式,效率较低,但有很多便利
$str =~ s/.\K(.*)/ $1 =~ s[aeiou]igr /e;
现在我们可以在该正则表达式中使用比tr
更复杂的工具;在这种情况下,它只是 i
标志,用于区分大小写-insensitive。
如果要保留的第一个字符不止一个,请将 .
更改为 .N
。
† 当然,Regex 不是强制性的。更基本的做法:split 将字符串转换为第一个字符和其余部分,然后在其余部分使用 tr
use warnings;
use strict;
use feature 'say';
my $str = shift // q(out with ALL vowels after first);
my ($result, $rest) = split //, $str, 2; # first char, rest of string
$result .= $rest =~ tr/aeiouAEIOU//dr; # prune $rest of vowels, append to $result
say $result;
然后把它放在一个小的迷你子程序中。要更改原始字符串,而不是获取新的 ($result
) 字符串,请在任何地方使用它 ($str
) 而不是 $result
。
我不确定它如何比较效率,但它可能会很好。
为了好奇,这里只写一个声明
$str = join '', map length > 1 ? tr/aeiouAEIOU//dr : $_ split //, $str, 2;
这特别使用了只需要跳过第一个(一个)字符的事实;只要标准确实涉及子字符串的长度,这很容易实现动态化。
更重要的是,这假设字符串的其余部分长于 1 个字符。要放弃该假设,请更改标准
use feature 'state';
$str = join '', map
state $chr_cnt = 0;
++$chr_cnt > 1 ? tr/aeiouAEIOU//dr : $_
split //, $str, 2;
这也依赖于只保留一个字符。它使用feature 在执行过程中保持一个词法值state。
更通用的解决方案,它使用substr 的属性可以写入
substr($str, 1) =~ tr/aeiouAEIOU//d;
在这里放宽对第一个字符的限制更加简洁:只需更改 1
即可跳过更多字符。棘手的——意想不到的——部分可能是通常内置函数不能像那样写入,它们不是lvalue subroutines
【讨论】:
您好,谢谢。我们还没有被介绍过正则表达式,所以作为一年级的学生,我正在研究我们迄今为止所学到的东西。还有另一种使用 for 循环的方法吗?这就是我想要做的。 @Traveller 嗨——你展示的尝试使用tr
,这是一个正则表达式风格的想法。是的,您可以通过基本方法来做到这一点——将字符串分解为字符并遍历该列表,只保留满足您条件的那些:第一个或非元音。 (但话又说回来,要检查一个字符是否不是元音,你会使用正则表达式——因为替代方案并不漂亮——五向 if
语句!)但你真的不能这样做首先学习至少一些 Perl!
这是我周一到期的作业。因此,如果没有正则表达式,我需要将其拆分为单词并稍后编写一个 if 语句。
@Traveller 一种基本方法:拆分为字符(不是“单词”),然后遍历该列表,将每个字符与元音进行比较;如果它匹配任何一个元音,它就不会被保留。如果您不能使用正则表达式,我认为您必须依次对每个元音执行eq
。跳过第一个,保留。但是——你试试tr
——这是否允许?如果是,则将字符串拆分为第一个字符和其余字符,并将tr
应用于其余字符,然后将它们合并回来。
@Traveller (我不知道当您显然不了解该语言时您将如何在 Perl 中做到这一点?您能在几天内掌握最基本的知识吗?有可能.)【参考方案2】:
解决问题的算法在你的问题中
如果字符串不是元音,则在字符串中添加字母 如果它是输入字符串中的第一个元音,则在字符串中添加字母use strict;
use warnings;
my $x = "without any vowels after the first letter\n";
my($o,$count) = ('',0);
print 'IN: ' . $x;
for ( split('',$x) )
$o .= $_ unless $count != 0 and /[aeiou]/i;
$count++ if /[aeiou]/i;
print 'OUT: ' . $o;
输出
IN: without any vowels after the first letter
OUT: witht ny vwls ftr th frst lttr
附录:OP对问题的澄清
查看句子中的每个单词 如果单词以元音开头,则删除除第一个以外的所有元音 如果单词从无元音开始,则删除所有元音use strict;
use warnings;
use feature 'say';
my $x = 'I like apples more than oranges';
my @o;
say 'IN: ' . $x;
for ( split(' ', $x) )
if ( /^[aeiou]/i )
s/.\K(.*)/$1 =~ tr|aeiouAEIOU||dr/e;
else
tr|aeiouAEIOU||d;
@o = (@o,$_);
say 'OUT: ' . join(' ', @o);
输出
IN: I like apples more than oranges
OUT: I lk appls mr thn orngs
或者在perlish风格
use strict;
use warnings;
use feature 'say';
my $x = "I like apples more than oranges";
say 'IN: ' . $x;
say 'OUT: ' . join(' ', map s/.\K(.*)/$1 =~ tr|aeiouAEIOU||dr/e && $_ split('[ ]+', $x));
输出
IN: I like apples more than oranges
OUT: I lk appls mr thn orngs
【讨论】:
您好,谢谢。在这一个中,所有元音都被删除。如果元音是单词中的第一个字母,我需要一个元音所在的位置。 @Traveller 你的问题有点模糊,你必须纠正它以反映你试图实现的目标。为了获得最佳结果,您必须提供一些输入和预期输出示例。 我编辑了我最初创建的代码。抱歉,如果我的问题晦涩难懂,我也对其进行了编辑 @Traveler -- 我是否理解正确:$str = 'astringing';
将变为 $str = 'astringing';
和 $str = 'stringing'
变为 $str = 'strngng
?为清楚起见,在您的问题中添加一些示例。
它会变成'astrngng'。 "a" 将保留,因为它位于字母的开头。 “我”将消失。以上是关于如何删除句子中除了第一个字母的元音之外的所有元音?的主要内容,如果未能解决你的问题,请参考以下文章
如何编写一个函数,将句子中每个单词开头的所有辅音字符串转换为“r”,直到它变成元音?
Leetcode练习(Python):第345题:反转字符串中的元音字母:编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
Leetcode练习(Python):第345题:反转字符串中的元音字母:编写一个函数,以字符串作为输入,反转该字符串中的元音字母。