2013-05-09 16 views
6

Sto usando listadmin per gestire molte mailing list basate su mailman. Ho una lunga lista di argomenti e da indirizzi impostati per bloccare lo spam. Recentemente, ho ricevuto più intelligente di spam, nel senso che utilizza simpatici personaggi dall'aspetto Unicode, ad esempio:Perl: Come abbinare FULLWIDTH LATIN SMALL

Oggetto: Al l l'annuncio ULT mov i si' hai vedere nulla nare c ompari- ng al nostro Exx xci ti ng compilation di 13'000 movimenti in HD t hat sono disponibili per te adesso!

o

Oggetto: HD qua y acceso VI D EOS uno d ​​pho per rappresentare graficamente s o f Ho ff hic tc
sono qui per u

Ora voglio usa una regex intelligente Perl per bloccarla. Piping questi soggetti a hexdump ha rivelato che molti personaggi sono un FULLWIDTH LATIN SMALL LETTER. Tuttavia, non funziona: Can't find Unicode property definition "FULLWIDTH LATIN SMALL LETTER"

Quindi la domanda è: c'è un \p{something} corrispondente a quei caratteri a larghezza intera? In alternativa: c'è un altro modo per abbinare quei personaggi?

risposta

8

La pagina perlunicode documenti disponibili classi di caratteri unicode. L'ho trovato come riferimento in perlrebackslash, che documenta speciali classi di caratteri e sequenze di backslash come \p{...} in regex.

Il riepilogo è che tutte le classi di proprietà tranne le più comuni richiedono un tipo di proprietà e un valore di proprietà, che sono separati da : o =. Tuttavia, non sembra esserci menzione dei caratteri a larghezza piena come proprietà predefinita.

Ma v'è di proprietà Block/Blk, che può avere Halfwidth and Fullwidth Forms (U+FF00 - U+FFEF) come valore:

/\p{Block=Halfwidth and Fullwidth Forms}/ 

Ciò corrisponderà sul tuo ingresso (testato su v16.3).


Uno strumento utile per questo è uniprops.

$ uniprops U+FF41 
U+FF41 ‹a› \N{FULLWIDTH LATIN SMALL LETTER A} 
    \w \pL \p{LC} \p{L_} \p{L&} \p{Ll} 
    All Any Alnum Alpha Alphabetic Assigned InHalfwidthAndFullwidthForms 
    Cased Cased_Letter LC Changes_When_Casemapped CWCM 
    Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT 
    Changes_When_Uppercased CWU Ll L Gr_Base Grapheme_Base Graph GrBase 
    Halfwidth_And_Fullwidth_Forms Hex XDigit Hex_Digit ID_Continue IDC 
    ID_Start IDS Letter L_ Latin Latn Lowercase_Letter Lower Lowercase 
    Print Word XID_Continue XIDC XID_Start XIDS X_POSIX_Alnum 
    X_POSIX_Alpha X_POSIX_Graph X_POSIX_Lower X_POSIX_Print X_POSIX_Word 
    X_POSIX_XDigit 

Come si può vedere, \p{Block=Halfwidth and Fullwidth Forms} può anche essere scritto \p{In Halfwidth and Fullwidth Forms}.

+0

molte grazie @ikegami per la modifica illuminante e il modulo d'intrattenimento lascia collegato. – amon

+0

È uno di Tchrist's. 'unichars' può essere usato per fare il contrario. per esempio. 'unichars -au '\ p {InHalfwidthAndFullwidthForms}'' elenca i caratteri nel blocco HalfwidthndFullwidthForms. – ikegami

4

È possibile utilizzare charnames::viacode per ottenere i nomi dei personaggi dai loro codici:

#!/usr/bin/perl 
use warnings; 
use strict; 
use utf8; 

use charnames qw(); 


my $string = q(Subject: Al l the ad ult mov ies you' ve see n a r e nothing) 
      .q(c ompari- ng t o our exx xci t i ng compilation of 13' 000) 
      .q(mov ies in HD t hat are a v ailable for y ou now!); 

my $count = grep /FULLWIDTH/, map charnames::viacode(ord), split //, $string; 
print "$count fullwidth characters.\n"; 
Problemi correlati