Почему [^\w] соответствует некоторым символам слова, но не [^\p{Word}]?

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

Но это распечатывает ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ ÿ среди совпадающих символов [^\w], Эти персонажи должны скорее совпадать \w, Как ни странно, они совпадают \p{Word},

Я пытался без успеха:

  • map { decode ( "UTF-8", $_ ) }
  • map { pack 'U0C*', unpack 'C*', $_ }

Как я могу сделать [^\w] не соответствуют этим словам символов?

chars.pl

#!/usr/bin/perl

use warnings;
use strict;
use utf8;

binmode STDOUT, ':utf8';

my $c;
my $cols = 80;
my $arg = shift;
my $regex = qr/$arg/;

for ( map { chr } 0x20 .. 0xFFFF )
{
  next if /\p{Unassigned}|\p{NChar}|\p{Cs}/;

  if ( $_ =~ $regex )
  {
    print STDOUT;
    print STDOUT "\n" if ++$c % $cols == 0;
  }

}

print STDOUT "\n" if defined $c and $c % $cols != 0;
exit 0;

Хорошо:

$ ./chars.pl '\p{Cyrillic}'
ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя
ѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁ҂҃҄҇ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡ
ҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӏӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱ
ӲӳӴӵӶӷӸӹӺӻӼӽӾӿԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԐԑԒԓԔԕԖԗԘԙԚԛԜԝԞԟԠԡԢԣԤԥԦԧᴫᵸⷠⷡⷢⷣⷤⷥⷦⷧⷨⷩⷪⷫⷬⷭⷮⷯⷰⷱⷲⷳⷴⷵⷶⷷ
ⷸⷹⷺⷻⷼⷽⷾⷿꙀꙁꙂꙃꙄꙅꙆꙇꙈꙉꙊꙋꙌꙍꙎꙏꙐꙑꙒꙓꙔꙕꙖꙗꙘꙙꙚꙛꙜꙝꙞꙟꙠꙡꙢꙣꙤꙥꙦꙧꙨꙩꙪꙫꙬꙭꙮ꙯꙰꙱꙲꙳꙼꙽꙾ꙿꚀꚁꚂꚃꚄꚅꚆꚇꚈꚉꚊꚋꚌꚍꚎꚏ
ꚐꚑꚒꚓꚔꚕꚖꚗ
$

Хорошо:

$ ./chars.pl '[^\p{Word}]' | grep É
$

Плохой:

$ ./chars.pl '[^\w]' | grep É
°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
$

Perl v5.14.2

1 ответ

Решение

Поддержка Unicode в Perl - огромная тема, см., Например, этот ответ

Делать \w соответствует так же, как \p{Word}, тебе нужно иметь /u действует модификатор набора символов (доступен в Perl начиная с версии 5.14).

Самый простой способ - просто запустить программу с

use v5.14;

которая (помимо прочего) включает функцию unicode_strings и делает все регулярные выражения по умолчанию /u модификатор набора символов. Вы также можете просто включить эту функцию явно:

use feature 'unicode_strings';

Третий способ заключается в использовании /u изменено в регулярном выражении, чтобы изменить набор символов для каждого регулярного выражения.

Вы можете прочитать об эффектах различных модификаторов набора регулярных выражений из man- страницы perlre. Это /d, /u, /a а также /l,

\w объясняется на странице perlrecharclass.

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