這段代碼有什么問題?我該如何糾正?
$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 中不正確的字串。(澄清這是我認為在這個問題中有用的一部分。)
uj5u.com熱心網友回復:
首先,其中大部分不是 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修飾符,這使得替換端被評估為代碼,因此它在那里運行獨立的音譯 ( tr),處理捕獲的子字串。
然后我們需要嵌入的/regex 中的/r修飾符tr,以回傳新字串而不是更改舊字串 - 無論如何都無法更改,因為無法更改$1。
還可以使用 regex insteda tr,效率較低,但具有許多便利
$str =~ s/.\K(.*)/ $1 =~ s{[aeiou]}{}igr /e;
現在我們可以在正則運算式中使用比在tr; 中更復雜的工具;在這種情況下,它是唯一的i標志,用于區分我nsensitive。
如果它是一個比第一個字符,以保持更多的變化.來.{N}。
? 當然,正則運算式不是強制性的。一個更基本的看法:分裂串入它的第一個字符,剩下的,然后使用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;
這也依賴于只留下一個字符。它使用一個特性來保持跨執行的詞法值state。
A more generic solution, which uses the property of substr to be possible to write to
substr($str, 1) =~ tr/aeiouAEIOU//d;
Here it's much cleaner and simpler to relax the limitation to the first character: just change that 1 in order to skip more characters. The tricky -- unexpected -- part here may be that normally builtins can't be written to like that, they aren't lvalue subroutines
uj5u.com熱心網友回復:
解決問題的演算法在你的問題中
- 如果不是元音,則向字串添加字母
- 如果它是輸入字串中的第一個元音,則向字串添加字母
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316283.html
上一篇:在Perl標簽中顯示HTML
