Perl: 8 ou 10 caractères distincts
s///
solution: 10 distinctes, 13 au total
La technique sed (supposée; voir ci-dessous) fonctionne toujours aussi en perl, et donne le nombre de noms de caractères distincts (10):
s/[aeiou]//gi
Par exemple:
$ 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.
C'est 10 caractères distincts, comme cela le prouve:
$ echo 's/[aeiou]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
10
Le problème avec la solution sed est qu'elle ne/i
fait pas partie de POSIX sed et n'est donc pas portable:
$ 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'
Cela fonctionne sur un système OpenBSD. En revanche, comme il /i
fait en effet toujours partie de Perl standard, vous pouvez compter sur sa présence permanente. Contrairement à sed.
Si vous voulez inclure "y" dans la liste des voyelles, c'est bien sûr un de plus si vous utilisez la même technique:
$ 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
Et c'est maintenant 14 caractères au total.
tr[][]
solution: 8 distincts 10 au total
Vous pouvez également utiliser tr///
pour supprimer tout ce qui correspond. Perl peut même utiliser l' y///
alias de sed pour tr
:
y/aeiou//d
qui est maintenant 8 caractères distincts, mais ne fonctionne pas en majuscules. Vous finissez par devoir ajouter 5 caractères supplémentaires pour faire face aux casemaps:
$ echo 'y/aeiouAEIOU//d' | perl -nle '@s{split//}=(); print scalar keys %s'
13
et bien sûr, c'est maintenant 15 au total.
Cependant, l'ajout de «y» au mélange comme voyelle n'augmente pas le nombre de caractères distincts comme il l'a fait avec la s///
version:
$ 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.
Il ne s'agit donc que des 8 originaux distincts sur un total de 11:
$ echo 'y/aeiouy//d' | perl -nle '@s{split//}=(); print scalar keys %s'
8
EDIT : Comptabilisation des diacritiques
Et qu'en est-il des entrées Renée’s naïveté
? La sortie correcte devrait bien sûr être Rn’s nvt
. Voici comment faire cela, en utilisant le /r
drapeau de la v5.14 pour s///
:
$ echo 'Renée’s naïveté' |
perl5.14.0 -CS -MUnicode::Normalize -nle 'print NFD($_)=~s/[aeiou]\pM*//rgi'
Rn’s nvt
C'est 27 caractères distincts:
$ echo 'print NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
27
Vous pouvez couper que 26 si vous pouvez garantir que vous utilisez au moins v5.10 en échangeant le print
pour 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
Et vous pouvez le ramener à 22 si cela ne vous dérange pas de déplacer les diacritiques au lieu de les supprimer:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]//rgi'
Rń’s n̈vt́
Ce qui est ... intéressant à regarder, c'est le moins qu'on puisse dire. :) Voici son compte distinct:
$ echo 'say NFD($_) =~ s/[aeiou]//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
22
Bonne chance pour obtenir une autre langue pour gérer correctement les signes diacritiques en utilisant moins de caractères que cela!