8

我正在寻找一种仅匹配 Unicode 字符串中完全组成的字符的方法。

是否[:print:]依赖于包含此字符类的任何正则表达式实现中的语言环境?例如,它会匹配日文字符“あ”,因为它不是控制字符,还是[:print:]总是 ASCII 码 0x20 到 0x7E?

是否有任何字符类(包括 Perl RE)可用于匹配控制字符以外的任何内容?如果[:print:]仅包含 ASCII 范围内的字符,我会假设[:cntrl:]也包含。

4

5 回答 5

6
echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"'

这主要是有效的,尽管它会生成一个关于宽字符的警告。但它给了你一个想法:你必须确保你正在处理一个真正的 unicode 字符串(检查 utf8::is_utf8)。或者只是检查perlunicode - 整个主题仍然让我头晕目眩。

于 2008-10-15T05:27:30.287 回答
5

我认为您不需要或不需要语言环境,而是Unicode。如果您已解码文本字符串,\w将匹配任何语言中的单词字符,\d不仅匹配0..9每个 Unicode 数字等。在正则表达式中,您可以使用\p{PropertyName}. 对你来说特别有趣的可能是\p{Print}这是所有可用 Unicode 字符属性的列表

我写了一篇关于 Unicode 和 Perl 的基础知识和精妙之处的文章,它应该让你很好地了解 perl 会将你的字符串识别为一个字符序列,而不仅仅是一个字节序列。

更新:使用 Unicode,您不会获得依赖于语言的行为,而是无论语言如何,都是合理的默认值。这可能是您想要的,也可能不是您想要的,但是为了区分可打印/控制字符,我不明白为什么您需要依赖语言的行为。

于 2008-10-15T06:48:26.190 回答
4

\X匹配一个完全组合的字符(序列)。证明:

#!/usr/bin/env perl
use 5.010;
use utf8;
use Encode qw(encode_utf8);

for my $string (qw(あ ご ご), "\x{3099}") {
    say encode_utf8 sprintf "%s $string", $string =~ /\A \X \z/msx ? 'ok' : 'nok';
}

测试数据是:一个普通字符、一个预组合字符、一个组合字符序列和一个组合字符(它本身“不算数”,对Unicode第3章的简化)。

替换\X[[:print:]]看到 Tanktalus 的答案在最后两种情况下产生错误匹配。

于 2010-01-07T23:12:47.990 回答
2

是的,这些表达式取决于语言环境。

于 2008-10-15T03:11:14.803 回答
1

您始终可以使用字符类[^[:cntrl:]]来匹配非控制字符。

于 2008-10-15T03:26:58.080 回答