4

我正在为我的应用程序使用 SimpleDB。除非一个属性的限制是 1024 字节,否则一切顺利。因此,对于长字符串,我必须将字符串切成块并保存。

我的问题是,有时我的字符串包含 unicode 字符(中文、日文、希腊文),并且该substr()函数基于字符数而不是字节。

我尝试使用use bytes字节语义或更高版本 substr(encode_utf8($str), $start, $length),但它根本没有帮助。

任何帮助,将不胜感激。

4

2 回答 2

5

UTF-8 的设计使字符边界易于检测。要将字符串拆分为有效的 UTF-8 块,您可以简单地使用以下命令:

my $utf8 = encode_utf8($text);
my @utf8_chunks = $utf8 =~ /\G(.{1,1024})(?![\x80-\xBF])/sg;

然后要么

# The saving code expects bytes.
store($_) for @utf8_chunks;

或者

# The saving code expects decoded text.
store(decode_utf8($_)) for @utf8_chunks;

示范:

$ perl -e'
    use Encode qw( encode_utf8 );

    # This character encodes to three bytes using UTF-8.
    my $text = "\N{U+2660}" x 342;

    my $utf8 = encode_utf8($text);
    my @utf8_chunks = $utf8 =~ /\G(.{1,1024})(?![\x80-\xBF])/sg;

    CORE::say(length($_)) for @utf8_chunks;
'
1023
3
于 2012-04-24T17:42:52.353 回答
2

substr除非字符串具有 UTF-8 标志,否则对 1 字节字符进行操作。因此,这将为您提供解码字符串的前 1024 个字节:

substr encode_utf8($str), 0, 1024;

虽然,不一定在字符边界上拆分字符串。要在最后丢弃任何拆分字符,您可以使用:

$str = decode_utf8($str, Encode::FB_QUIET);
于 2012-04-24T17:24:31.830 回答