Как мне сопоставить только полностью составленные символы в строке Unicode в Perl? - PullRequest
8 голосов
/ 15 октября 2008

Я ищу способ сопоставления только полностью составленных символов в строке Unicode.

[:print:] зависит от локали в любой реализации регулярного выражения, которая включает этот класс символов? Например, будет ли он соответствовать японскому символу «あ», поскольку он не является управляющим символом или [:print:] всегда будет ASCII-кодом от 0x20 до 0x7E?

Существует ли какой-либо класс символов, включая Perl RE, который можно использовать для сопоставления с чем-либо кроме управляющего символа? Если [:print:] включает только символы в диапазоне ASCII, я бы предположил, что [:cntrl:] тоже.

Ответы [ 5 ]

6 голосов
/ 15 октября 2008
echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"'

Это в основном работает, хотя генерирует предупреждение о широком символе. Но это дает вам идею: вы должны быть уверены, что имеете дело с реальной строкой Unicode (проверьте utf8 :: is_utf8). Или просто отметьте perlunicode - весь объект все еще заставляет мою голову вращаться.

5 голосов
/ 15 октября 2008

Я думаю, вы не хотите или не нуждаетесь в локалях для этого, но, скорее, в Юникоде. Если вы расшифровали текстовую строку, \w будет соответствовать символам слова на любом языке, \d соответствует не просто 0..9, но каждой цифре Unicode и т. Д. В регулярных выражениях вы можете запрашивать свойства Unicode с помощью \p{PropertyName}. Особенно интересным для вас может быть \p{Print}. Вот список всех доступных свойств символов Unicode .

Я написал статью об основах и тонкостях Unicode и Perl , она должна дать вам хорошее представление о том, что делать, чтобы Perl распознавал вашу строку как последовательность символов, а не просто последовательность байтов.

Обновление: с Unicode вы не получаете зависимое от языка поведение, но вместо этого вменяемые значения по умолчанию независимо от языка. Это может быть, а может и не быть тем, что вы хотите, но из-за различий в качестве символа для управления / контроля я не понимаю, почему вам нужно поведение, зависящее от языка.

4 голосов
/ 08 января 2010

\X соответствует полностью составленному символу (последовательности). Доказательство:

#!/usr/bin/env perl
use 5.010;
use utf8;
use Encode qw(encode_utf8);

for my $string (qw(あ ご ご), "\x{3099}") {
    say encode_utf8 sprintf "%s $string", $string =~ /\A \X \z/msx ? 'ok' : 'nok';
}

Тестовые данные: нормальный символ, предварительно объединенный символ, последовательность символов объединения и символ объединения (который сам по себе «не считается», упрощение главы 3 Unicode).

Замените \X на [[:print:]], чтобы увидеть, что ответ Tanktalus дает ложные совпадения для двух последних случаев.

2 голосов
/ 15 октября 2008

Да, эти выражения зависят от локали.

1 голос
/ 15 октября 2008

Вы всегда можете использовать класс символов [^[:cntrl:]] для сопоставления неуправляемых символов.

...