我无法从字符串中去除特殊字符¤和❤:
$word = 'cɞi¤r$c❤u¨s';
$word =~ s/[^a-zöäåA-ZÖÄÅ]//g;
printf "$word\n";
在第二行,我尝试从字符串$word
中删除任何非字母字符。我期望得到单词circus的输出结果,但实际上输出了:
ci�rc�us
表达式中的öäå和ÖÄÅ只是瑞典字母表中的普通字符,我需要包含它们。
我无法从字符串中去除特殊字符¤和❤:
$word = 'cɞi¤r$c❤u¨s';
$word =~ s/[^a-zöäåA-ZÖÄÅ]//g;
printf "$word\n";
在第二行,我尝试从字符串$word
中删除任何非字母字符。我期望得到单词circus的输出结果,但实际上输出了:
ci�rc�us
表达式中的öäå和ÖÄÅ只是瑞典字母表中的普通字符,我需要包含它们。
如果字符在您的源代码中,请确保使用 utf8
。 如果它们是从文件中读取的,请使用binmode $FILEHANDLE, ':utf8'
。
请务必阅读 perldoc perlunicode
。
printf 'cɞi¤r$c❤u¨söäå';
。但当我运行正则表达式时出现了问题。从正则表达式中删除 öäå 可以解决问题,但这样我就不能在字符串中使用这些字符 :/ - Pithikosuse utf8
,您仍然可以打印字符串,但在这种情况下,Perl 打印的是 字节 而不是 _字符_。这也是为什么它无法识别正则表达式中的字符。您读过 perlunicode
吗? - choroba简短回答:添加"use utf8;"语句,确保源代码中的文字字符串被解释为utf8编码,包括测试字符串和正则表达式的内容。
详细回答:
#!/usr/bin/env perl
use warnings;
use Encode;
my $word = 'cɞi¤r$c❤u¨s';
foreach my $char (split //, $word) {
print ord($char) . Encode::encode_utf8(":$char ");
}
my $allowed_chars = 'a-zöäåA-ZÖÄÅ';
print "\n";
foreach my $char (split //, $allowed_chars) {
print ord($char) . Encode::encode_utf8(":$char ");
}
print "\n";
$word =~ s/[^$allowed_chars]//g;
printf Encode::encode_utf8("$word\n");
没有使用utf8执行:
$ perl utf8_regexp.pl
99:c 201:É 158: 105:i 194:Â 164:¤ 114:r 36:$ 99:c 226:â 157: 164:¤ 117:u 194:Â 168:¨ 115:s
97:a 45:- 122:z 195:Ã 182:¶ 195:Ã 164:¤ 195:Ã 165:¥ 65:A 45:- 90:Z 195:Ã 150: 195:Ã 132: 195:Ã 133:
ci¤rc¤us
使用UTF8执行:
$ perl -Mutf8 utf8_regexp.pl
99:c 606:ɞ 105:i 164:¤ 114:r 36:$ 99:c 10084:❤ 117:u 168:¨ 115:s
97:a 45:- 122:z 246:ö 228:ä 229:å 65:A 45:- 90:Z 214:Ö 196:Ä 197:Å
circus
解释:
您在源代码中输入的非ascii字符由一个或多个字节表示。由于您的输入是utf8编码的,在纯ascii或latin-1终端中,这些字符将只占用一个字节。
当不使用utf8模块时,perl认为您输入的每个字节都是一个单独的字符,就像在拆分并打印每个单独的字符时所看到的那样。使用utf8模块时,它根据utf8编码规则正确地将几个字节组合成一个字符。
可以看到,令人巧合的是,一些瑞典字符由某些测试字符串中的一些字符由的字节匹配,并且被保留下来。即:ö在utf8中由195:Ã 164:¤组成 - 164最终成为您允许的一个字符,并通过了字符串验证。
解决方案是告诉perl你的字符串应该被视为utf-8。
encode_utf8调用的目的是避免警告将宽字符打印到终端。始终需要根据输入或输出应处理/操作的字符编码进行解码输入和编码输出。
希望这样更加清晰易懂。
choroba所指出的, 将这段代码添加到perl脚本开头即可解决问题:
use utf8;
binmode(STDOUT, ":utf8");
use utf8
让你可以在正则表达式中正确使用特殊字符,而binmode(STDOUT, ":utf8")
则让你在 shell 中正确输出特殊字符。
use utf8
是一个代码片段。在我看来,他是在让我使用utf8,但我不知道如何“使用utf8”,因此无法将其翻译成任何有意义的内容。期望初学者理解你的行话并不是一种教学方法。 - Pithikos
perl -v
命令打印版本。Perl Unicode 手册。 - cfi