2010-03-30 115 views
2

我有目录路径列表,需要过滤掉其中的一些。我的匹配模式采用非Unicode编码。如何为俄文字母做出不区分大小写的正则表达式匹配?

我试过如下:

require 5.004; 
use POSIX qw(locale_h); 
my $old_locale = setlocale(LC_ALL); 
setlocale(LC_ALL, "ru_RU.cp1251"); 

@{$data -> {doc_folder_rights}} = 
     grep { 
       # catalog path pattern in $_REQUEST{q} 
       $_->{doc_folder} =~/$_REQUEST{q}/i; 
      } 
      @{$data -> {doc_folder_rights}}; 

setlocale(LC_ALL, $old_locale); 

当模式包含russsian字母我需要的是不区分大小写的正则表达式模式匹配。

+0

你的perl版本是什么?我相信perl 5.004不支持那些正则表达式。 – 2010-03-30 08:37:02

+0

'perl -v'输出:'v5.10.0针对x86_64-linux-gnu-thread-multi' – jonny 2010-03-30 08:51:13

回答

2

有几个(潜在的)问题与您的代码:

  1. 您的代码过滤掉所有doc_folders是匹配的正则表达式中$_REQUEST{q},但是这个问题建议你要反其道而行之。

  2. 您可能有编码问题。设置语言环境(使用setlocale)会更改perl对小写转换的处理,但不会更改任何编码。你需要确保$_REQUEST{q}被正确解释。

为了简单起见,你可以认为任何Perl的字符串包含一些内部表示,你不需要了解详细的Unicode数据。只有当Perl做I/O时才会有一个隐式或显式的转换。从标准输入,ARGV或环境中读取时,Perl会假定字节使用当前语言环境进行编码并隐式转换。

如果你有一个编码问题,有几种方法来解决这个问题:

  1. 修复在Perl中运行,因此它知道从一开始就正确的区域设置环境。这将修复隐式转换。
  2. 在从文件句柄加载$_REQUEST的情况下,您可以明确告诉Perl使用binmode($fh, ":encoding(cp1251)");进行转换。这样做之前阅读$_REQUEST
  3. $string = Encode::decode(Encoding, $octets)函数告诉Perl忘记其有关$octets编码的假设,而是将$octets的内容视为需要使用Encoding转换为Unicode的字节流。在触摸$octets的内容之前,您需要这样做,否则可能会发生奇怪的事情。
  4. 由于$_REQUEST可能是由一些cgi模块加载的,并且可能是在传输过程中进行了网址编码,所以您可以告诉cgi模块如何正确进行解码。
相关问题