Как мне сопоставить только полностью составленные символы в строке Unicode в Perl?

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

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

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

5 ответов

Решение
echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"'

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

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

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

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

\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:]] чтобы увидеть, что ответ Танкталуса дает ложные совпадения для последних двух случаев.

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

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

Другие вопросы по тегам