代码之家  ›  专栏  ›  技术社区  ›  jonny

如何使不区分大小写的regexp与俄语字母匹配?

  •  3
  • jonny  · 技术社区  · 15 年前

    我有目录路径的列表,需要过滤掉其中的一些。我的匹配模式是非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);
    

    我需要的是当模式包含俄语字母时不区分大小写的regexp模式匹配。

    1 回复  |  直到 13 年前
        1
  •  2
  •   edgar.holleis    15 年前

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

    1. 你的代码过滤掉所有 匹配中的regexp $_REQUEST{q} 但是问题表明你想做相反的事。

    2. 您可能有编码问题。设置语言环境(使用setLocale)会更改Perl对大小写转换的处理,但不会更改任何编码。你得保证 $i请求{q} 正确解释。

    为了简单起见,您可以假设任何perl字符串都在一些不需要详细了解的内部表示中包含unicode数据。只有当Perl进行I/O时,才会有隐式或显式转换。从stdin、argv或environment读取时,perl假定字节是使用当前语言环境编码的,并隐式转换。

    如果存在编码问题,有几种方法可以解决:

    1. 修复perl运行的环境,以便它从一开始就知道正确的语言环境。这将修复隐式转换。
    2. 在不太可能的情况下 $_REQUEST 是从文件句柄加载的,可以显式地告诉perl使用 binmode($fh, ":encoding(cp1251)"); . 在阅读之前 $i请求 .
    3. $string = Encode::decode(Encoding, $octets) 告诉perl忘记其关于 $octets 而是处理 八位字节 作为字节流,需要使用 Encoding . 在接触 八位字节 ,否则可能会发生奇怪的事情。
    4. 自从 $i请求 可能是由某个cgi模块加载的,也可能是在传输过程中被url编码的,您可以告诉cgi模块如何正确地进行解码。