Perl: 8 или 10 различных символов
s///
Решение: 10 отдельных, 13 всего
Техника sed (предполагаемая; см. Ниже) также всегда работает в perl и выдает количество имен различных символов (10):
s/[aeiou]//gi
Например:
$ echo 'This program will remove VOWELS. So we can speak without them.' |
perl -ple 's/[aeiou]//gi'
Ths prgrm wll rmv VWLS. S w cn spk wtht thm.
Это 10 различных символов, как это доказывает:
$ echo 's/[aeiou]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
10
Проблема с решением sed заключается в том, что /i
он не является частью sed POSIX и, следовательно, не является переносимым:
$ echo 'This program will remove VOWELS. So we can speak without them.' |
sed -e 's/[aeiou]//gi'
sed: 1: "s/[aeiou]//gi": bad flag in substitute command: 'i'
Это работает в системе OpenBSD. Напротив, поскольку /i
он действительно всегда является частью стандартного Perl, вы можете рассчитывать на его постоянное присутствие. В отличие от сед.
Если вы хотите включить «y» в список гласных, это, конечно, еще лучше, если вы используете ту же технику:
$ echo 'This nifty program remove any VOWELS. So we easily can speak without them.' |
perl -ple 's/[aeiouy]//gi'
Ths nft prgrm rmv n VWLS. S w sl cn spk wtht thm.
$ echo 's/[aeiouy]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
11
И это теперь всего 14 символов.
tr[][]
решение: 8 различных 10 всего
Вы также можете использовать tr///
для удаления все, что соответствует. Perl может даже использовать y///
псевдоним sed для tr
:
y/aeiou//d
который теперь 8 различных символов, но не работает в верхнем регистре. В итоге вам придется добавить еще 5 символов, чтобы справиться с картами дел:
$ echo 'y/aeiouAEIOU//d' | perl -nle '@s{split//}=(); print scalar keys %s'
13
и, конечно же, сейчас всего 15.
Тем не менее, добавление «y» в микс в качестве гласного не увеличивает количество отдельных символов, как в s///
версии:
$ echo 'This nifty program remove any VOWELS. So we easily can speak without them.' |
perl -ple 'y/aeiouy//d'
Ths nft prgrm rmv n VOWELS. S w sl cn spk wtht thm.
Так что это все еще только оригинальные 8 из 11:
$ echo 'y/aeiouy//d' | perl -nle '@s{split//}=(); print scalar keys %s'
8
РЕДАКТИРОВАТЬ : Учет диакритических знаков
А как насчет входов, как Renée’s naïveté
? Правильный вывод, конечно, должен быть Rn’s nvt
. Вот как это сделать, используя /r
флаг v5.14 для s///
:
$ echo 'Renée’s naïveté' |
perl5.14.0 -CS -MUnicode::Normalize -nle 'print NFD($_)=~s/[aeiou]\pM*//rgi'
Rn’s nvt
Это 27 разных персонажей:
$ echo 'print NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
27
Вы можете обрезать его до 26, если вы можете гарантировать, что вы работаете по крайней мере v5.10, заменяя print
на say
:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]\pM*//rgi'
Rn’s nvt
$ echo 'say NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
26
И вы можете уменьшить его до 22, если не возражаете перемещать диакритические знаки вместо их удаления:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]//rgi'
Rń’s n̈vt́
На что ... интересно смотреть, если не сказать больше. :) Вот его отчетливый счет:
$ echo 'say NFD($_) =~ s/[aeiou]//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
22
Удачи вам найти любой другой язык для правильной работы с диакритическими знаками, используя меньше символов, чем этот!