1

我正在使用 perl 代码库来验证客户输入,我的目标是阻止代理字符。

我的想法是首先将客户输入编码为 UTF-16 和

 foreach my $messageChar (@MessageChars) {
   my $messageCharUTF16 = Encode::encode("UTF-16", $messageChar);
   if (($messageCharUTF16 >= 0xD800 && $messageCharUTF16 <= 0xDBFF)|( $messageCharUTF16 >= 0xDC00 && $messageCharUTF16 <= 0xDFFF)) {
      // Then we have surrogate pairs       
   }   
 }

但是,我没有从 Encode::encode 获得正确的 UTF-16 值。

如何显示代理对?是否有任何直接的方法来验证字符串是否包含 Perl 中的代理字符?

4

1 回答 1

4

我不清楚您要检查什么,因此我将介绍这两种可能性。


检查解码后的字符串是否包含任何 U+D800..U+DFFF

官方的 Unicode 标准说没有任何 UTF 形式,包括 UTF-16,可以编码这些代码点,Perl 有义务。

$ perl -e'use open ":std", ":encoding(UTF-8)"; print "ABC\N{U+D800}DEF\n";'
Unicode surrogate U+D800 is illegal in UTF-8 at -e line 1.
"\x{d800}" does not map to utf8 at -e line 1.
ABC\x{D800}DEF

要检查这些字符,您可以使用

$str =~ /[\x{D800}-\x{DFFF}]/

要检查任何编码错误,您可以使用

eval { encode("UTF-8", $str, Encode::FB_CROAK | Encode::LEAVE_SRC); 1 }

检查解码后的字符串是否包含高于 U+FFFF 的字符

U+FFFF 以上的字符不能使用 UCS-2 编码,需要代理才能使用 UTF-16 编码。

$ perl -e'use open ":std", ":encoding(UTF-16le)"; print "\N{U+10000}";' | od -t x2
0000000 d800 dc00
0000004

要检查这些字符,您可以使用

$str =~ /[^\0-\x{FFFF}]/
于 2018-03-22T03:58:45.100 回答