2009-07-25 10 views
6

Senza eseguire il ciclo sull'intero intervallo di caratteri Unicode, come è possibile ottenere un elenco di caratteri con una determinata proprietà? In particolare voglio un elenco di tutti i caratteri che sono cifre (ad esempio quelli che corrispondono a /\d/). Ho guardato a Unicode::UCD ed è utile per determinare le proprietà di un determinato carattere, ma non sembra essere un modo per ottenere un elenco di caratteri che hanno una proprietà al di fuori di esso.Come si ottiene un elenco di tutti i caratteri Unicode con una determinata proprietà?

risposta

6

L'elenco dei caratteri Unicode per ogni classe viene generato dalla specifica Unicode quando si compila il Perl, ed è tipicamente memorizzati in/usr/lib/perl-YOURPERLVERSION/unicore/lib/gc_sc/

Ad esempio, l'elenco degli intervalli di caratteri Unicode che corrispondono a IsDigit (aka \ d) è archiviato nel file /usr/lib/perl-YOURPERLVERSION/unicore/lib/gc_sc/Digit.pl

+0

Grazie, questo è quasi esattamente quello che stavo cercando. Avrò ancora un ciclo su di loro per costruire una lista, ma almeno non ci vorrà per sempre e un giorno. –

0

quali caratteri/\ d/corrisponde dipende interamente dall'implementazione regexp (sebbene siano garantiti lo standard 0-9). Nel caso di perl, il codice perl locale utilizzato definisce quali caratteri sono considerati alfabetici e cifre.

+0

Perl trasforma stringhe in utf8 prima di eseguirli attraverso il motore regex. L'unica cosa che influenza le impostazioni locali di perl è come una stringa di byte grezza viene trasformata in utf8. Una volta che una stringa è in utf8, perl utilizzerà sempre la stessa definizione di IsDigit, indipendentemente dalle impostazioni locali. – tetromino

0

Non c'è modo di farlo senza iterare attraverso tutti i personaggi. (se crei una stringa enorme con tutti loro e usi una regexp devi ancora fare il ciclo almeno una volta, per creare la stringa).

+0

Fortunatamente parte del Perl processo di generazione crea una serie di file sotto 'unicore' in una delle directory lib che hanno già un sacco di lavoro fatto per voi. Non so se sono ufficiali o meno, ho una domanda nella lista Perl 5 Porters per scoprire se è sicuro usarli. –

1

Anche meglio di unicore/lib/gc_sc/Digit.pl è unicore/To/Digit.pl. È una mappatura diretta dei caratteri numerici Unicode (beh, in realtà i loro offset) ai loro valori numerici. Ciò significa che invece di:

use Unicode::Digits qw/digit_to_int/; 

my @digits; 
for (split "\n", require "unicore/lib/gc_sc/Digit.pl") { 
    my ($s, $e) = map hex, split; 
    for (my $ord = $s; $ord <= $e; $ord++) { 
     my $chr = chr $ord; 
     push @{$digits[digits_to_int $chr]}, $chr; 
    } 
} 

for my $i (0 .. 9) { 
    my $re = join '', "[", @{$digits[$i]}, "]"; 
    $digits[$i] = qr/$re/; 
} 

posso dire:

my @digits; 
for (split "\n", require "unicore/To/Digit.pl") { 
    my ($ord, $val) = split; 
    my $chr = chr hex $ord; 
    push @{$digits[$val]}, $chr; 
} 

for my $i (0 .. 9) { 
    my $re = join '', "[", @{$digits[$i]}, "]"; 
    $digits[$i] = qr/$re/; 
} 

O ancora meglio:

my @digits; 
for (split "\n", require "unicore/To/Digit.pl") { 
    my ($ord, $val) = split; 
    $digits[$val] .= "\\x{$ord}"; 
} 
@digits = map { qr/[$_]/ } @digits; 
Problemi correlati