带有 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 A "A" LATIN CAPITAL LETTER A
040 32 0x20   " " SPACE, SP
0341 225 0xE1 á "á" LATIN SMALL LETTER A WITH ACUTE
040 32 0x20   " " SPACE, SP
0334 220 0xDC Ü "Ü" LATIN CAPITAL LETTER U WITH DIAERESIS
040 32 0x20   " " SPACE, SP
0321 209 0xD1 Ñ "Ñ" LATIN CAPITAL LETTER N WITH TILDE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
062745 26085 0x65E5 日 "日" CJK UNIFIED IDEOGRAPH-#65E5, IRGKangXi=0489.010, RSKangXi=72.0, Def{sun; day; daytime}
063454 26412 0x672C 本 "本" CJK UNIFIED IDEOGRAPH-#672C, IRGKangXi=0509.070, RSKangXi=75.1, Def{root, origin, source; basis}
0105236 35486 0x8A9E 語 "語" CJK UNIFIED IDEOGRAPH-#8A9E, IRGKangXi=1163.080, RSKangXi=149.7, Def{language, words; saying, expression}
040 32 0x20   " " SPACE, SP
061 49 0x31 1 "1" DIGIT ONE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
0177421 65297 0xFF11 1 "1" FULLWIDTH DIGIT ONE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
057 47 0x2F / "/" SOLIDUS
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
0137 95 0x5F _,_ "_" 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 / _
我正在尝试 'fix' 使用带有 '''\N{UNICODE NAME}''' 构造的 perl 正则表达式来处理一些具有意外 unicode 字符的文件。但是由于某种我不完全理解的原因,没有任何反应,但没有错误消息。 这是一个简单的测试例子。
[2007]$ read ZZ < test.txt && unum "${ZZ}"
Octal Decimal Hex HTML Character Unicode
0101 65 0x41 A "A" LATIN CAPITAL LETTER A
040 32 0x20   " " SPACE, SP
0341 225 0xE1 á "á" LATIN SMALL LETTER A WITH ACUTE
040 32 0x20   " " SPACE, SP
0334 220 0xDC Ü "Ü" LATIN CAPITAL LETTER U WITH DIAERESIS
040 32 0x20   " " SPACE, SP
0321 209 0xD1 Ñ "Ñ" LATIN CAPITAL LETTER N WITH TILDE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
062745 26085 0x65E5 日 "日" CJK UNIFIED IDEOGRAPH-#65E5, IRGKangXi=0489.010, RSKangXi=72.0, Def{sun; day; daytime}
063454 26412 0x672C 本 "本" CJK UNIFIED IDEOGRAPH-#672C, IRGKangXi=0509.070, RSKangXi=75.1, Def{root, origin, source; basis}
0105236 35486 0x8A9E 語 "語" CJK UNIFIED IDEOGRAPH-#8A9E, IRGKangXi=1163.080, RSKangXi=149.7, Def{language, words; saying, expression}
040 32 0x20   " " SPACE, SP
061 49 0x31 1 "1" DIGIT ONE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
0177421 65297 0xFF11 1 "1" FULLWIDTH DIGIT ONE
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
057 47 0x2F / "/" SOLIDUS
040 32 0x20   " " SPACE, SP
040 32 0x20   " " SPACE, SP
0137 95 0x5F _,_ "_" 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 / _