2013-04-30 15 views
5

Byłem dziś rano recenzowany i znalazłem trochę kodu, który był błędny, ale nie mogłem powiedzieć dlaczego.Jak wydrukować klasę znaków Perla?

$line =~ /^[1-C]/; 

Linia ta została przypuszczać, aby ocenić na postać szesnastkową między 1 i C, ale zakładam, że linia ta nie robi. Pytanie nie jest zgodne, ale co to pasuje? Czy mogę wydrukować wszystkie postacie w klasie znaków? Coś jak poniżej?

say join(', ', [1-C]); 

Niestety

# Examples: 
say join(', ', 1..9); 
say join(', ', 'A'..'C'); 
say join(', ', 1..'C'); 

# Output 
Argument "C" isn't numeric in range (or flop) at X:\developers\PERL\Test.pl line 33. 

1, 2, 3, 4, 5, 6, 7, 8, 9 
A, B, C 
+0

Nie bezpośrednio na temat tego pytania, ale należy chyba podkreślić, że właściwym wyliczeniem dopasowania liczby heksadecymalnej między 1 a C jest "/ [0-9A-C] /". – bpj

Odpowiedz

16

Dopasowuje każdy punkt kodu z U + 0030 ("1") do 0043 U + ("C").

Odpowiedź jest prosta w użyciu

map chr, ord("1")..ord("C") 

zamiast

"1".."C" 

jak widać w poniższej prezentacji:

$ perl -Mcharnames=:full -E' 
    say sprintf " %s U+%05X %s", chr($_), $_, charnames::viacode($_) 
     for ord("1")..ord("C"); 
' 
1 U+00031 DIGIT ONE 
2 U+00032 DIGIT TWO 
3 U+00033 DIGIT THREE 
4 U+00034 DIGIT FOUR 
5 U+00035 DIGIT FIVE 
6 U+00036 DIGIT SIX 
7 U+00037 DIGIT SEVEN 
8 U+00038 DIGIT EIGHT 
9 U+00039 DIGIT NINE 
: U+0003A COLON 
; U+0003B SEMICOLON 
< U+0003C LESS-THAN SIGN 
= U+0003D EQUALS SIGN 
> U+0003E GREATER-THAN SIGN 
? U+0003F QUESTION MARK 
@ U+00040 COMMERCIAL AT 
A U+00041 LATIN CAPITAL LETTER A 
B U+00042 LATIN CAPITAL LETTER B 
C U+00043 LATIN CAPITAL LETTER C 

Jeśli masz Unicode::Tussle zainstalowany, można uzyskać ten sam wynik z następującej komendy powłoki:

unichars -au '[1-C]' 

Możesz być zainteresowany traceniem czasu na przeglądanie Unicode code charts. (. Ten szczególny zakres objęty jest "alfabetu łacińskiego (ASCII)")

+0

+1 Doskonałe wyjaśnienie. Bardzo prosta. – JDB

+0

@ Cyborgx37, Dzięki. Po prostu zrobiło się jeszcze lepiej :) – ikegami

+0

Podoba mi się użycie mapy i "od U + 0030 (" 1 ") do U + 0043 (" C ")", bardzo wiele musiałem wiedzieć. dzięki –

0

[1-9A-C] jest to ilość zgodnych z sześciokątnym pomiędzy 1 i C

[a char - an another char] spełniają wszystkie znaki pomiędzy dwoma znaków w tabeli Unicode

+0

Z OP: * "Nie chodzi o to, co pasuje, ale co to pasuje?" *. Nie sądzę, że OP szuka właściwego rozwiązania, ale jest ciekawy, jak pokazać, co pasuje do zakresu znaków. Być może musi udowodnić, że klasa postaci jest niepoprawna. – JDB

+0

Oczywiście, ale może on sprawdzić tablice znaków wikipedia, aby to wiedzieć. –

+1

Wiesz o tym i wiem o tym, ale nie sądzę, że OP wiedział o tym. W każdym razie nie odpowiada to na pytanie, które może wyjaśnić zdanie. – JDB

3

jest to prosty program do testowania zakres tego RegExpr:

use strict; 
use warnings; 
use Test::More qw(no_plan); 

for(my $i=ord('1'); $i<=ord('C'); $i++) { 
    my $char = chr($i); 
    ok $char =~ /^[1-C]/, "match: $char"; 
} 

wygenerować ten wynik:

ok 1 - match: 1 
ok 2 - match: 2 
ok 3 - match: 3 
ok 4 - match: 4 
ok 5 - match: 5 
ok 6 - match: 6 
ok 7 - match: 7 
ok 8 - match: 8 
ok 9 - match: 9 
ok 10 - match: : 
ok 11 - match: ; 
ok 12 - match: < 
ok 13 - match: = 
ok 14 - match: > 
ok 15 - match: ? 
ok 16 - match: @ 
ok 17 - match: A 
ok 18 - match: B 
ok 19 - match: C 
1..19 
Powiązane problemy