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





Да, эти выражения зависят от локали.
Вы всегда можете использовать класс символов [^[:cntrl:]] для сопоставления неуправляющих символов.
Это не соответствует управляющим символам Unicode (в моей настройке среды и с использованием Perl). Есть управляющие символы Unicode для изменения направления текста и так далее. Использование [^ [: ctrnl:]] будет соответствовать этим Unicode, но не ASCII.
echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"'
В основном это работает, хотя генерирует предупреждение о широком символе. Но это дает вам идею: вы должны быть уверены, что имеете дело с реальной строкой Unicode (проверьте utf8 :: is_utf8). Или просто проверьте перлуникод вообще - от всей темы у меня все равно кружится голова.
Вы можете избавиться от уродливого кладжа BEGIN {binmode STDIN, ": utf8"}, указав опцию -CS в командной строке.
... это также приведет к исчезновению предупреждения, потому что он устанавливает STDOUT так же, как STDIN.
Это может быть не так уж и много, если OP пишет модуль для обработки этого вместо отдельного скрипта. Поэтому я собираюсь оставить свое решение, а также ваше исправление в надежде, что OP сможет выяснить, какое из них лучше для его / ее сценария. Спасибо :-)
Это неправильный образец. [[: print:]] будет соответствовать "\ x {3099}", который не является полностью составным символом! См. Мой ответ для рабочего шаблона.
Я думаю, что для этого вам не нужны или нужны локали, а скорее Unicode. Если вы декодировали текстовую строку, \w будет соответствовать символам слова на любом языке, \d соответствует не только 0..9, но и каждой цифре Unicode и т. д. В регулярных выражениях вы можете запрашивать свойства Unicode с помощью \p{PropertyName}. Особенно интересным для вас может быть \p{Print}. Вот список всех доступных свойств символов Юникода..
Я написал статья об основах и тонкостях 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:]], чтобы увидеть, что ответ Tanktalus дает ложные совпадения для последних двух случаев.
Можете ли вы назвать среду и / или реализацию регулярного выражения, которая позволяет [: print:] уважать японскую локаль / кодировку UTF-8? Я использую Perl в Linux с японской локалью / кодировкой UTF-8, и он не соответствует японскому символу.