Как мне сопоставить только полностью составленные символы в строке 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:]]
сопоставлять неконтролируемые символы.