5

文档都将我引导到 unicode 支持,但我认为我的请求与 Unicode 没有任何关系。我想在单个标量的上下文中使用原始字节;我需要能够计算出它的长度(以字节为单位),获取它的子字符串(以字节为单位),将字节写入磁盘,并通过网络。有没有一种简单的方法可以做到这一点,而不将字节视为 perl 中的任何类型的编码?

编辑

更明确地说,

my $data = "Perl String, unsure of encoding and don't need to know";
my @data_chunked_into_1024_bytes_each = #???
4

3 回答 3

6

Perl 字符串在概念上是字符串它们是 32 位正整数,(通常)表示 Unicode 代码点。在 Perl 中,字节字符串只是一个字符串,其中所有字符的值都小于 256。

(这是概念视图。内部表示有点复杂,因为 perl 解释器试图将字节字符串存储为上述意义上的实际字节字符串,同时对包含字符值 256 的字符串使用通用 UTF-8 编码或更高。但这一切都应该对用户透明,实际上大多数情况下都是透明的,除了一些丑陋的历史极端情况,如按位非 ( ~) 运算符。)

至于如何将一般字符串转换为字节字符串,这实际上取决于您拥有的字符串包含什么以及字节字符串应该包含什么:

  • 如果你的字符串已经一个字节串——例如,如果你以二进制模式从文件中读取它——那么你不需要做任何事情。该字符串不应包含任何超过 255 的字符,如果包含,则这是一个错误,并且可能会由加密代码报告。

  • 同样,如果您的字符串应该以 ASCII 或 ISO-8859-1 编码(分别编码 Unicode 的 7 位和 8 位子集)编码文本,那么您不需要做任何事情:任何字符最多255 已经正确编码,任何更高的值对于这些编码都是无效的。

  • 如果您的输入字符串包含要以其他编码进行编码的 (Unicode) 文本,那么您需要将字符串转换为该编码。通常的方法是使用Encode模块,如下所示:

    use Encode;
    my $byte_string = encode( "name of encoding", $text_string );
    

    显然,您可以使用以下命令将字节字符串转换回相应的字符串:

    use Encode;
    my $text_string = decode( "name of encoding", $byte_string );
    
  • 对于 UTF-8 编码的特殊情况,也可以使用内置utf8::encode()函数代替Encode::encode()

    utf8::encode( $string );
    

    它与以下内容基本相同:

    use Encode;
    $string = encode( "utf8", $string );
    

    请注意,与 不同Encode::encode()的是,该utf8::encode()函数直接修改输入字符串。还要注意,"utf8"上面提到了 Perl 的扩展 UTF-8 编码,它允许超出官方 Unicode 范围的值;对于严格符合标准的 UTF-8 编码,请使用"utf-8"连字符(有关血腥细节,请参阅编码文档)。而且,是的,还有一个utf8::decode()功能几乎可以满足您的期望。

于 2012-09-16T22:37:22.467 回答
1

如果我正确理解了您的问题,您想要的是打包/解包功能: http: //perldoc.perl.org/functions/pack.html

于 2012-09-16T21:12:52.413 回答
1

只要您的字符串不包含高于代码点 255 的字符,它将主要用作纯字节字符串,lengthsubstr使用字节进行操作。此外,大多数输出​​函数,如print默认情况下期望八位字节/字节,如果您尝试向它们填充任何其他内容,实际上会抱怨。

如果已知输出采用某种编码,您可能需要显式编码/解码输出,但只有在您针对程序的每个有问题的部分提出另一个特定问题时,才能添加更多详细信息。

于 2012-09-16T21:37:47.797 回答