Как я могу сделать регистр без учета регистра для русских букв? - PullRequest
3 голосов
/ 30 марта 2010

У меня есть список каталогов и мне нужно отфильтровать некоторые из них. Мой шаблон совпадений не в кодировке 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);

Что мне нужно, так это сопоставление с регулярным выражением без учета регистра, когда шаблон содержит русские буквы.

1 Ответ

2 голосов
/ 30 марта 2010

Есть несколько (потенциальных) проблем с вашим кодом:

  1. Ваш код отфильтровывает все папки документов, которые не соответствуют регулярному выражению в $_REQUEST{q}, однако вопрос предполагает, что вы хотите сделать обратное.

  2. У вас может быть проблема с кодировкой. Установка языкового стандарта (используя setlocale) изменяет обработку perl преобразований в верхнем и нижнем регистре, но не меняет никакой кодировки. Вы должны убедиться, что $_REQUEST{q} интерпретируется правильно.

Для простоты вы можете предположить, что любая Perl-строка содержит Unicode-данные в некотором внутреннем представлении, о котором вам не нужно подробно знать. Только когда Perl делает ввод / вывод, происходит неявное или явное преобразование. При чтении из stdin, ARGV или окружения Perl предполагает, что байты кодируются с использованием текущей локали, и неявно преобразует.

Если у вас есть проблема с кодировкой, есть несколько способов ее исправить:

  1. Исправьте среду, в которой работает Perl, чтобы он знал о правильной локали с самого начала. Это исправит неявное преобразование.
  2. В маловероятном случае, когда $_REQUEST загружается из файлового дескриптора, вы можете явно указать Perl конвертировать, используя binmode($fh, ":encoding(cp1251)");. Сделайте это до прочтения $_REQUEST.
  3. Существует функция $string = Encode::decode(Encoding, $octets), которая заставляет Perl забыть свое предположение о кодировке $octets и вместо этого обрабатывать содержимое $octets как поток байтов, который необходимо преобразовать в Unicode с помощью Encoding. Это необходимо сделать перед тем, как дотронуться до содержимого $octets, иначе могут произойти странные вещи.
  4. Поскольку $_REQUEST, вероятно, был загружен каким-то cgi-модулем и, вероятно, был кодирован в кодировке URL при передаче, вы можете просто сказать cgi-модулю, как правильно выполнять декодирование.
...