2011-05-20 88 views
5

当我这样做:Perl的正则表达式预编译 - UTF8

use strict; use warnings; 
my $regex = qr/[[:upper:]]/; 
my $line = MyModule::get_my_line_from_external_source(); #file, db, etc... 
print "upper here\n" if($line =~ $regex); 

怎样使用Perl会知道什么时候它只能ascii uppercaseutf8 uppercase匹配吗? 这是一个预编译的正则表达式 - 所以有些Perl必须知道,什么是大写。取决于区域设置?如果是,如何将“C”语言环境中的utf8大写与预编译的正则表达式匹配?

更新基于tchrist的评论:

use strict; use warnings; use Encode; 
my $regex = qr/[[:upper:]]/; 

my $line = XXX::line(); 
print "$line: upper1 ", ($line =~ $regex) ? "YES" : "NO", "\n"; 

my $uline = Encode::decode_utf8($line); 
print "$uline: upper2 ", ($uline =~ $regex) ? "YES" : "NO", "\n"; 

package XXX; 
sub line { return "alpha-Ω"; } #returning octets - not utf8 chars 

输出是:

alpha-Ω: upper1 NO 
alpha-Ω: upper2 YES 

是什么意思,是预编译的正则表达式是不是“硬预编译”,而是“软预编译” - 所以perl根据匹配的$行的utf8标志替换'[[:upper:]]'。

+0

如果您在源代码中使用文字UTF-8,那么您只需要在作用域中使用“utf8”。 Perl会为你解码。 – tchrist 2011-05-20 14:09:46

回答

6

在Perl 5.14之前,这个没有很好的定义。

随着5.14,知道这是如何被编译的模式,你有/u/l/d/a,或/aa图案修饰。你也可以说

use re "/u"; 

use re "/msu"; 

把所有的这些标志上的词汇范围。

例如,在5.14:

% perl -le 'print qr/foo/' 
(?^:foo) 
% perl -E 'say qr/foo/' 
(?^u:foo) 
% perl -E 'say qr/foo/l' 
(?^l:foo) 

我STEAR明确的语言环境;只使用全Unicode。

顺便说一句,我会确保这个“外部源”给你一个正确解码的字符串;也就是说,它的UTF8标志打开了。字符函数在编码字符串上效果不佳,因为它们确实需要解码字符串。

+1

那么,在perl <5.14中匹配utf8 [:upper:]的正确方法是什么?例如:“my $ regsrc = Encode :: decode_utf8('[[:upper:]]');我的$ regex = qr/$ regsrc /;#或者怎么样?或者在开始时足够放入”use utf8;“? – kobame 2011-05-20 12:52:48

+0

'使用utf8'不足以在U + 80-U + FF上为自己的源代码获取Unicode字符串语义,您应该可以说'utf :: upgrade($ string)'。已经被解码了,否则就是UTF-8的正确编码,如果是这样的话,就表示它已经解码了,然后任何正则表达式都可以正常工作,你可以使用'utf8 :: is_utf8($ string)'来测试它的UTF8标志已经打开,Unicode属性'\ p {upper}'将假定Unicode语义,但是这又要求字节字符串已经被转换为字符串了,我永远不会使用'[[:upper:]]'' , – tchrist 2011-05-20 13:05:49

+0

优先考虑[Unicode :: Semantics](http://p3rl.org/Unicode::Semantics)而不是裸体'upgrade' API调用,不需要执行'is_utf8'测试 – daxim 2011-05-20 13:14:03