Perl: 8 hoặc 10 ký tự riêng biệt
s///
Giải pháp: 10 khác biệt, tổng cộng 13
Kỹ thuật sed (có mục đích; xem bên dưới) cũng luôn hoạt động theo perl và mang lại số tên của các ký tự riêng biệt (10):
s/[aeiou]//gi
Ví dụ:
$ 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.
Đó là 10 ký tự riêng biệt, vì điều này chứng tỏ:
$ echo 's/[aeiou]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
10
Vấn đề với giải pháp sed là nó không phải/i
là một phần của POSIX sed và do đó không thể mang theo được:
$ 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'
Đó là chạy trên hệ thống OpenBSD. Ngược lại, vì /i
thực sự luôn là một phần của perl tiêu chuẩn, bạn có thể tin tưởng vào nó luôn ở đó. Không giống như sed.
Nếu bạn muốn bao gồm các món y lòng trong danh sách các nguyên âm, thì tất nhiên sẽ tốt hơn nếu bạn sử dụng cùng một kỹ thuật:
$ 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
Và bây giờ là 14 nhân vật.
tr[][]
giải pháp: 8 tổng 10 khác biệt
Bạn cũng có thể sử dụng tr///
để loại bỏ bất cứ thứ gì nó phù hợp. Perl thậm chí có thể sử dụng y///
bí danh của sed cho tr
:
y/aeiou//d
hiện có 8 ký tự riêng biệt, nhưng không hoạt động bằng chữ hoa. Cuối cùng, bạn phải thêm 5 ký tự nữa để đối phó với các casemaps:
$ echo 'y/aeiouAEIOU//d' | perl -nle '@s{split//}=(); print scalar keys %s'
13
và tất nhiên đó là 15 tổng số.
Tuy nhiên, việc thêm vào y lòng vào hỗn hợp dưới dạng nguyên âm không làm tăng số lượng ký tự riêng biệt như đã làm với s///
phiên bản:
$ 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.
Vì vậy, đó vẫn chỉ là 8 bản gốc khác biệt trong tổng số 11:
$ echo 'y/aeiouy//d' | perl -nle '@s{split//}=(); print scalar keys %s'
8
EDIT : Kế toán cho Diacritics
Và những gì về đầu vào như thế Renée’s naïveté
nào? Đầu ra chính xác nên là tất nhiên Rn’s nvt
. Đây là cách để làm điều đó, sử dụng /r
cờ của v5,14 cho s///
:
$ echo 'Renée’s naïveté' |
perl5.14.0 -CS -MUnicode::Normalize -nle 'print NFD($_)=~s/[aeiou]\pM*//rgi'
Rn’s nvt
Đó là 27 nhân vật riêng biệt:
$ echo 'print NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
27
Bạn có thể cắt nó thành 26 nếu bạn có thể đảm bảo rằng bạn đang chạy ít nhất v5.10 bằng cách hoán đổi print
cho 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
Và bạn có thể giảm xuống còn 22 nếu bạn không ngại di chuyển dấu phụ thay vì xóa chúng:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]//rgi'
Rń’s n̈vt́
Đó là ... thú vị để xem xét, để nói rằng ít nhất. :) Đây là số lượng riêng biệt của nó:
$ echo 'say NFD($_) =~ s/[aeiou]//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
22
Chúc may mắn nhận được bất kỳ ngôn ngữ khác để đối phó với dấu phụ bằng cách sử dụng ít ký tự hơn thế này!