4

Rebol 3 を使用して、Latin1 のファイルを読み取り、UTF-8 に変換したいと考えています。使用できる組み込み関数、または外部ライブラリはありますか? どこで見つけられますか?

4

4 に答える 4

4

Rebolには無効なutfがありますか? 有効な UTF-8 シーケンスの一部ではないバイトのバイナリ値を精査する関数。それらをすべて見つけて置き換えるまでループし、バイナリ値を文字列に変換します。

latin1-to-utf8: function [binary [binary!]][
    mark: :binary
    while [mark: invalid-utf? mark][
        change/part mark to char! mark/1 1
    ]
    to string! binary
]

この関数は元のバイナリを変更します。代わりに、バイナリ値をそのまま残す新しい文字列を作成できます。

latin1-to-utf8: function [binary [binary!]][
    mark: :binary
    to string! rejoin collect [
        while [mark: invalid-utf? binary][
            keep copy/part binary mark  ; keeps the portion up to the bad byte
            keep to char! mark/1        ; converts the bad byte to good bytes
            binary: next mark           ; set the series beyond the bad byte
        ]
        keep binary                     ; keep whatever is remaining
    ]
]

おまけ: 上記のちょっとしたRebmuバージョンがあります — <code>rebmu/args snippet #{DECAFBAD} ここsnippetで:

; modifying
IUgetLOAD"invalid-utf?"MaWT[MiuM][MisMtcTKm]tsA

; copying
IUgetLOAD"invalid-utf?"MaTSrjCT[wt[MiuA][kp copy/partAmKPtcFm AnxM]kpA]
于 2014-04-05T02:47:19.620 に答える
4

これは、少し高速で、少なくともメモリの使用量が少ないバージョンです。

latin1-to-utf8: func [
    "Transcodes a Latin-1 encoded string to UTF-8"
    bin [binary!] "Bytes of Latin-1 data"
] [
    to binary! head collect/into [
        foreach b bin [
            keep to char! b
        ]
    ] make string! length? bin
]

対応する Unicode コードポイントと同じ数値を持つ Latin-1 文字を利用します。そうでない別の文字セットから変換したい場合は、 で計算を実行しbて文字を再マッピングできます。

メモリの使用量が少なく、さまざまな理由で高速です。

  • 通常、collectブロックを作成します。文字列をターゲットとして使用collect/intoして渡します。文字列は、整数または文字のブロックよりも少ないメモリを使用します。
  • 文字列を入力データの長さに事前に割り当て、再割り当てを節約します。
  • 独自の計算を行うのではなく、Rebol のネイティブ コードに文字を変換させます。
  • ループ内のコードが少ないため、実行速度が速くなります。

この方法でも、ファイルを一度にメモリにロードし、結果を格納するための中間値を生成しますが、少なくとも中間値は小さくなります。おそらくこれにより、より大きなファイルを処理できるようになります。

UTF-8 にする必要がある理由が、Rebol でファイルを文字列として処理する必要があるためである場合は、をスキップしto binary!て文字列をそのまま返します。または、バイナリソースデータを処理するだけで、バイナリのバイトをto char!それぞれに使用して変換するだけです。

于 2014-02-13T19:45:12.750 に答える
3

現時点では何も組み込まれていません。これは、私が書いて少し前に Rebol 3 で使用した、Latin-1 から UTF-8 への変換の簡単な実装です。

latin1-to-utf8: func [
    "Transcodes a Latin-1 encoded string to UTF-8"
    bin [binary!] "Bytes of Latin-1 data"
] [
    to-binary collect [foreach b bin [keep to-char b]]
] 

注: このコードは読みやすさのために最適化されており、パフォーマンスのために最適化されているわけではありません。(パフォーマンスの観点からは、まったくばかげています。警告されています。)

更新: @BrianH のきちんとした「Latin-1 バイト値は Unicode コードポイントに対応する」最適化を組み込みました。まだ。メモリ使用量に関するより最適化されたバージョンについては、@ BrianH の素敵な回答を参照してください。

于 2014-02-12T00:49:39.320 に答える
1
latin1-to-utf8: func [
    "Transcodes bin as a Latin-1 encoded string to UTF-8"
    bin [binary!] "Bytes of Latin-1 data"
    /local t
] [
    t: make string! length? bin
    foreach b bin [append t to char! b ]
    t
]
于 2014-03-30T00:15:30.243 に答える