2011-09-15 8 views
23

Per esempio, match "nazione" in "" Internazionalizzazione", senza moduli aggiuntivi. E 'possibile nelle nuove versioni Perl (5.14, 5.15, ecc)?Come abbinare la stringa con diacritico in perl?

ho trovato una risposta! Grazie a tchrist

soluzione rigth con UCA match (thnx a https://stackoverflow.com/users/471272/tchrist).

# found start/end offsets for matched utf-substring (without intersections) 
use 5.014; 
use strict; 
use warnings; 
use utf8; 
use Unicode::Collate; 
binmode STDOUT, ':encoding(UTF-8)'; 
my $str = "Îñţérñåţîöñåļîžåţîöñ" x 2; 
my $look = "Nation"; 
my $Collator = Unicode::Collate->new(
    normalization => undef, level => 1 
    ); 

my @match = $Collator->match($str, $look); 
if (@match) { 
    my $found = $match[0]; 
    my $f_len = length($found); 
    say "match result: $found (length is $f_len)"; 
    my $offset = 0; 
    while ((my $start = index($str, $found, $offset)) != -1) {             
     my $end = $start + $f_len; 
     say sprintf("found at: %s,%s", $start, $end); 
     $offset = $end + 1; 
    } 
} 

sbagliato (ma di lavoro) la soluzione da http://www.perlmonks.org/?node_id=485681

piece La magia di codice è: esempio

$str = Unicode::Normalize::NFD($str); $str =~ s/\pM//g; 

codice:

use 5.014; 
    use utf8; 
    use Unicode::Normalize; 

    binmode STDOUT, ':encoding(UTF-8)'; 
    my $str = "Îñţérñåţîöñåļîžåţîöñ"; 
    my $look = "Nation"; 
    say "before: $str\n"; 
    $str = NFD($str); 
    # M is short alias for \p{Mark} (http://perldoc.perl.org/perluniprops.html) 
    $str =~ s/\pM//og; # remove "marks" 
    say "after: $str";¬ 
    say "is_match: ", $str =~ /$look/i || 0; 
+1

+1 per l'esempio peloso. – Bojangles

+1

non so se c'è qualche sostegno diretto, ma si potrebbe canonicalize a Fully Scomposto, poi striscia tutti i caratteri con una 'unione' di proprietà (ISTR c'è una tale proprietà, anche se non sono sicuro di come si chiama) – tripleee

+1

googe "perl rimuovi tutti i diacritici" molte partite che sembrano promettenti –

risposta

7

soluzione Destra con UCA (thnx per tchrist):

# found start/end offsets for matched s 
use 5.014; 
use utf8; 
use Unicode::Collate; 
binmode STDOUT, ':encoding(UTF-8)'; 
my $str = "Îñţérñåţîöñåļîžåţîöñ" x 2; 
my $look = "Nation"; 
my $Collator = Unicode::Collate->new(
    normalization => undef, level => 1 
    ); 

my @match = $Collator->match($str, $look); 
say "match ok!" if @match; 

P.S. "Codice che presume che sia possibile rimuovere i segni diacritici per ottenere le lettere ASCII di base è malvagio, fermo, rotto, danneggiato dal cervello, sbagliato e giustificato per la pena capitale." © tchristWhy does modern Perl avoid UTF-8 by default?

6

Che cosa si intende per "senza moduli aggiuntivi"?

Ecco una soluzione con use Unicode::Normalize;see on perl doc

ho rimosso il "T" e "L" dalla stringa, la mia eclissi non ha voluto salvare lo script con loro.

use strict; 
use warnings; 
use UTF8; 
use Unicode::Normalize; 

my $str = "Îñtérñåtîöñålîžåtîöñ"; 

for ($str) { # the variable we work on 
    ## convert to Unicode first 
    ## if your data comes in Latin-1, then uncomment: 
    #$_ = Encode::decode('iso-8859-1', $_); 
    $_ = NFD($_); ## decompose 
    s/\pM//g;   ## strip combining characters 
    s/[^\0-\x80]//g; ## clear everything else 
} 

if ($str =~ /nation/) { 
    print $str . "\n"; 
} 

L'uscita è

Internationaliation

"Z" viene rimosso dalla stringa, sembra non essere un carattere composto.

Il codice per il ciclo for da questo lato How to remove diacritic marks from characters

Un'altra lettura interessante è The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) da Joel Spolsky

Aggiornamento:

Come @tchrist sottolineato, c'è un algoritmo esistente , che è più adatto, chiamato UCA (Unicode Collation Algorithm). @nordicdyno, ha già fornito un'implementazione nella sua domanda.

L'algoritmo è descritto qui Unicode Technical Standard #10, Unicode Collation Algorithm

modulo Perl è descritto qui perldoc.perl.org

+0

Grazie! Nel mio ambiente "ž" non è stato rimosso e tutto funziona correttamente. (vim + Mac OS X + perl 5.14.0) – nordicdyno

+3

Questo non è il modo per farlo. Vuoi una corrispondenza UCA di livello 1, che è solo alla forza primaria e quindi ignora i segni diacritici. – tchrist

+0

@tchrist Ho già imparato molto da te in merito all'unicode dalle tue risposte e commenti (grazie per questo), ma non penso ancora abbastanza. Ad essere onesti, non ho idea di cosa intendi con il tuo commento. (Che cos'è l'UCA?) – stema