2013-05-09 55 views
6

我使用listadmin来管理许多基于邮件的邮件列表。我有一个长长的主题列表以及用于阻止垃圾邮件的地址。最近,我在这个意义上收到垃圾邮件更聪明,它采用好看的Unicode字符,例如:Perl:如何匹配FULLWIDTH LATIN SMALL

主题:铝微升广告ULT MOV IES你已经看到的鼻孔什么ç ompari- 纳克我们EXX在HD 现在可以编辑13'000动画!

主题:高清QUA点燃Ÿ六ðEOS的d河粉到图形S 0˚F豪TC嗝KS
在这里为ü

现在我想使用智能Perl正则表达式来阻止它。将这些主题管道输送到hexdump显示很多字符是FULLWIDTH LATIN SMALL LETTER。但是,\p{FULLWIDTH LATIN SMALL LETTER}不起作用:Can't find Unicode property definition "FULLWIDTH LATIN SMALL LETTER"

所以问题是:是否有\p{something}匹配那些全角字符?或者:是否有另一种方法来匹配这些字符?

回答

8

页面perlunicode文件可用的unicode字符类。我发现它是perlrebackslash中的一个参考,它在正则表达式中记录特殊字符类和反斜杠序列,如\p{...}

总结是,除最常见的属性类别外,所有属性都需要属性类型和属性值,它们之间用:=分隔。但是,似乎没有提及全角字符作为预定义的属性。

但存在Block/Blk属性,它可以有Halfwidth and Fullwidth FormsU+FF00 - U+FFEF)的值:

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

这将匹配您的输入(上v16.3测试)。


一个有用的工具是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 

正如你所看到的,\p{Block=Halfwidth and Fullwidth Forms}也可以写\p{In Halfwidth and Fullwidth Forms}

+0

非常感谢@ikegami的启发编辑和娱乐模块它挂。 – amon 2013-05-09 23:26:09

+0

这是tchrist的。 “unichars”可以用来做相反的事情。例如'unichars -au'\ p {InHalfwidthAndFullwidthForms}'列出了HalfwidthAndFullwidthForms块中的字符。 – ikegami 2013-05-09 23:36:30

4

您可以使用charnames::viacode从他们的代码得到字符名称:

#!/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";