对于直接问题,您可能只需要\p{L}(信)Unicode Character Property
然而,更重要的是,解码所有输入并编码输出。
use warnings;
use strict;
use feature 'say';
use utf8; # allow non-ascii (UTF-8) characters in the source
use open ':std', ':encoding(UTF-8)'; # for standard streams
use Encode qw(decode_utf8); # @ARGV escapes the above
my $string = 'El Guapö';
if (@ARGV) {
$string = join ' ', map { decode_utf8($_) } @ARGV;
}
say "Input: $string";
$string =~ s/[^\p{L} ]//g;
say "Processed: $string";
当以 script.pl 123 El Guapö=_ 运行时
输入:123 El Guapö=_
加工:El Guapö
我使用了“毯子”\p{L} 属性(字母),因为缺少具体描述;如果/根据需要进行调整。 Unicode 属性提供了很多,请参阅上面的链接和perluniprops 的完整列表。
123 El 之间的空格仍然存在,最后可能会去掉前导(和尾随)空格。
注意还有\P{L},其中大写P表示否定。
上述简单的\pL 不适用于Combining Diacritical Marks,因为标记也会被删除。感谢jm666 指出这一点。
当重音“逻辑”字符(显示为单个字符)使用单独的字符作为其基字符和非空格标记(组合重音)时,就会发生这种情况。通常它的单个字符 (extended grapheme cluster) 及其代码点也存在。
例如:niño 中的ñ 是U+OOF1,但也可以写成"n\x{303}"。
要保持以这种方式书写的重音符号,请将 \p{Mn} (\p{NonspacingMark}) 添加到字符类中
my $string = "El Guapö=_ ni\N{U+00F1}o.* nin\x{303}o+^";
say $string;
(my $nodiac = $string) =~ s/[^\pL ]//g; #/ naive, accent chars get removed
say $nodiac;
(my $full = $string) =~ s/[^\pL\p{Mn} ]//g; # add non-spacing mark
say $full;
输出
El Guapö=_ niño.* niño+^
El Guapö niño nino
El Guapö niño niño
所以你想要s/[^\p{L}\p{Mn} ]//g 以保持组合重音。