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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
2 136
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Можете ли вы назвать среду и / или реализацию регулярного выражения, которая позволяет [: print:] уважать японскую локаль / кодировку UTF-8? Я использую Perl в Linux с японской локалью / кодировкой UTF-8, и он не соответствует японскому символу.

dreamlax 15.10.2008 07:14

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

Это не соответствует управляющим символам Unicode (в моей настройке среды и с использованием Perl). Есть управляющие символы Unicode для изменения направления текста и так далее. Использование [^ [: ctrnl:]] будет соответствовать этим Unicode, но не ASCII.

dreamlax 15.10.2008 08:03
Ответ принят как подходящий

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

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

Вы можете избавиться от уродливого кладжа BEGIN {binmode STDIN, ": utf8"}, указав опцию -CS в командной строке.

moritz 15.10.2008 10:43

... это также приведет к исчезновению предупреждения, потому что он устанавливает STDOUT так же, как STDIN.

moritz 15.10.2008 10:50

Это может быть не так уж и много, если OP пишет модуль для обработки этого вместо отдельного скрипта. Поэтому я собираюсь оставить свое решение, а также ваше исправление в надежде, что OP сможет выяснить, какое из них лучше для его / ее сценария. Спасибо :-)

Tanktalus 15.10.2008 17:35

Это неправильный образец. [[: print:]] будет соответствовать "\ x {3099}", который не является полностью составным символом! См. Мой ответ для рабочего шаблона.

daxim 08.01.2010 01:59

Я думаю, что для этого вам не нужны или нужны локали, а скорее 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 дает ложные совпадения для последних двух случаев.

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