带有 unicode 字符的 Perl 正则表达式替换不起作用,我错过了什么?

Perl regex substitutions with unicode character don't work, what am I missing?

我正在尝试 'fix' 使用带有 '''\N{UNICODE NAME}''' 构造的 perl 正则表达式来处理一些具有意外 unicode 字符的文件。但是由于某种我不完全理解的原因,没有任何反应,但没有错误消息。 这是一个简单的测试例子。

[2007]$ read ZZ < test.txt && unum "${ZZ}"
   Octal  Decimal      Hex        HTML    Character   Unicode
    0101       65     0x41       &#65;    "A"         LATIN CAPITAL LETTER A
     040       32     0x20       &#32;    " "         SPACE, SP
    0341      225     0xE1    &aacute;    "á"         LATIN SMALL LETTER A WITH ACUTE
     040       32     0x20       &#32;    " "         SPACE, SP
    0334      220     0xDC      &Uuml;    "Ü"         LATIN CAPITAL LETTER U WITH DIAERESIS
     040       32     0x20       &#32;    " "         SPACE, SP
    0321      209     0xD1    &Ntilde;    "Ñ"         LATIN CAPITAL LETTER N WITH TILDE
     040       32     0x20       &#32;    " "         SPACE, SP
     040       32     0x20       &#32;    " "         SPACE, SP
  062745    26085   0x65E5    &#26085;    "日"         CJK UNIFIED IDEOGRAPH-#65E5, IRGKangXi=0489.010, RSKangXi=72.0, Def{sun; day; daytime}
  063454    26412   0x672C    &#26412;    "本"         CJK UNIFIED IDEOGRAPH-#672C, IRGKangXi=0509.070, RSKangXi=75.1, Def{root, origin, source; basis}
 0105236    35486   0x8A9E    &#35486;    "語"         CJK UNIFIED IDEOGRAPH-#8A9E, IRGKangXi=1163.080, RSKangXi=149.7, Def{language, words; saying, expression}
     040       32     0x20       &#32;    " "         SPACE, SP
     061       49     0x31       &#49;    "1"         DIGIT ONE
     040       32     0x20       &#32;    " "         SPACE, SP
     040       32     0x20       &#32;    " "         SPACE, SP
 0177421    65297   0xFF11    &#65297;    "1"         FULLWIDTH DIGIT ONE
     040       32     0x20       &#32;    " "         SPACE, SP
     040       32     0x20       &#32;    " "         SPACE, SP
     057       47     0x2F       &sol;    "/"         SOLIDUS
     040       32     0x20       &#32;    " "         SPACE, SP
     040       32     0x20       &#32;    " "         SPACE, SP
    0137       95     0x5F &lowbar;,&UnderBar;    "_"         LOW LINE

现在,当我尝试使用 perl inline 替换一个字符作为测试时,例如

[2008]$ perl -p -e 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á Ü Ñ  日本語 1  1  /  _

没有错误,但也没有替换。我也试过了,

[2013]$ perl -e 'BEGIN { use charnames q{:full}; }' -p -e 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á Ü Ñ  日本語 1  1  /  _

没有变化。 我错过了什么,文档似乎暗示这应该有效?

如果我直接替换它会按预期工作,

[2015]$ perl -p -e 's/日+/X/gu;' test.txt
A á Ü Ñ  X本語 1  1  /  _

你必须告诉 perl 输入是 UTF-8,标准输出也是 UTF-8(好吧,后者可以跳过,但你会收到警告):

在一行中,-C 命令行选项参数控制什么被认为是 UTF-8:D 告诉 perl 使用 UTF-8 作为打开的 PerlIO 通道的默认编码(对于读和写;对于只读或只写还有其他选项;有关详细信息,请参阅 perlrun),并且 S 表示所有标准流(输入、输出和错误)都是 UTF-8编码。

所以...

$ perl -CDS -wpe 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á X Ñ  日本語 1  1  /  _