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
เป็นไม่ได้เป็นส่วนหนึ่งของ POSIX sed และจึงไม่ได้เป็นแบบพกพา:
$ 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 ตัวเพื่อรับมือกับ casemaps:
$ 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
เอาท์พุทที่ถูกต้องแน่นอนควรจะเป็น ต่อไปนี้เป็นวิธีดำเนินการโดยใช้แฟล็ก v5.14 /r
สำหรับ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
ขอให้โชคดีที่ได้ภาษาอื่นมาใช้จัดการกำกับโดยใช้ตัวอักษรน้อยกว่านี้มาก!