Perl скомпилированное регулярное выражение - utf8 - PullRequest
5 голосов
/ 20 мая 2011

Когда я делаю:

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 uppercase, а когда utf8 uppercase? Это предварительно скомпилированное регулярное выражение - поэтому Perl должен знать, что такое верхний регистр. Зависит от настроек локали? Если да, как сопоставить прописную букву utf8 в локали "C" с предварительно скомпилированным регулярным выражением?

обновлено на основе комментариев 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 replace «[[: upper:]]» на основе флага utf8 совпавшей строки $.

1 Ответ

6 голосов
/ 20 мая 2011

До 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)

Я бы держался подальше от локалей; просто используйте все-Unicode.

Кстати, я бы убедился, что этот «внешний источник» вернул вам строку, которая была правильно декодирована; то есть включен флаг UTF8. Символьные функции плохо работают с кодированными строками, потому что они действительно хотят декодированные строки вместо этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...