4

アプリケーションに SimpleDB を使用しています。1 つの属性の制限が 1024 バイトでない限り、すべてがうまくいきます。したがって、長い文字列の場合、文字列をチャンクに切り刻んで保存する必要があります。

私の問題は、文字列にユニコード文字 (中国語、日本語、ギリシャ語) が含まれていることがあり、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 に答える