はい、トリックがあります...これは、R2でも使用する必要があるトリックです。 文字列を使用しないでください。バイナリを使用してください!このようなことをしなければならない場合:
適切な回避策: #{F0908080}
Rebol2 でも機能し、Rebol3 でも機能します。面白いビジネスなしで保存してロードできます。
実際、Unicodeに関心がある場合は、 3 ではなく Rebol 2 で立ち往生している場合は、^(7F) よりも高いコードポイントを使用する文字列処理を停止してください。そのひどい回避策を見ると、その理由がわかります。
ひどい回避策: rejoin [#"^(F0)" #"^(90)" #"^(80)" #"^(80)"]
... "そして、その単一の UTF-8 コードポイントを持つ文字列を取得します" ...
取得する必要があるのは、4 つの個別の文字コードポイントと4 = length? terrible-workaround
. Rebol2は文字列で壊れています!基本的にバイナリと変わりません!フードの下。実際、Rebol2 では、AS-BINARY と AS-STRING を検索して、コピーを作成せずに 2 つの型を前後にエイリアスできます。(これは Rebol3 では不可能です。根本的に異なるため、機能に執着しないでください!)
これらの文字列が 4 の長さを報告するのを見るのはやや欺瞞的であり、変換すると各文字が同じ値を生成するという誤った安心感がありますto integer!
。それらをどこかのファイルまたはポートに書き出すことがあり、それらをエンコードする必要がある場合、噛まれるからです. Rebol2 でこれに注意してください。
>> to integer! #"^(80)"
== 128
>> to binary! #"^(80)"
== #{80}
しかし、R3 では、バイナリ変換が必要な場合に UTF-8 エンコーディングが使用されます。
>> to integer! #"^(80)"
== 128
>> to binary! #"^(80)"
== #{C280}
そのため、一見動作しているように見えるコードが後で別のことを行い、別の方法でシリアル化することになると、驚くことでしょう。実際、この点で R2 がどのように「めちゃくちゃ」になっているのか知りたい場合は、「mu」に奇妙な記号が付けられた理由を調べてください。R2:
>> to binary! #"^(03BC)"
== #{BC}
「03」を捨てただけです。:-/
したがって、何らかの理由で Unicode 文字列を操作する必要があり、R3 に切り替えることができない場合は、牛の例で次のようなことを試してください。
mu-utf8: #{03BC}
utf8: rejoin [#{} {Q: What does a Zen master's {Cow} Say? A: "} mu-utf8 {"!}]
これでバイナリが得られます。デバッグ出力用に文字列に変換するだけで、意味不明なものが表示される準備ができています。しかし、Rebol2 で行き詰まっている場合は、これを行うのが正しいことです。
そして、答えを繰り返します: Rebol3 でこれらのより高いコードポイントを使用する必要がある何らかの奇妙な理由で立ち往生した場合の対処方法でもあります。
utf8: rejoin [#{} {Q: What did the Mycenaean's {Cow} Say? A: "} #{010000} {"!}]
LINEAR B SYLLABLE B008 Aが何であるかを知っていたら、とても面白いジョークになると確信しています. これは、おそらく、この難解なことをしている場合、例として引用されているコードポイントがいくつかしかないということです。ほとんどのデータを便利なスロットに挿入する必要があるまで文字列として保持し、結果をバイナリ系列で保持できます。
更新:この問題が発生した場合は、一時的に回避するのに役立つユーティリティ関数を次に示します。
safe-r2-char: charset [#"^(00)" - #"^(7F)"]
unsafe-r2-char: charset [#"^(80)" - #"^(FF)"]
hex-digit: charset [#"0" - #"9" #"A" - #"F" #"a" - #"f"]
r2-string-to-binary: func [
str [string!] /string /unescape /unsafe
/local result s e escape-rule unsafe-rule safe-rule rule
] [
result: copy either string [{}] [#{}]
escape-rule: [
"^^(" s: 2 hex-digit e: ")" (
append result debase/base copy/part s e 16
)
]
unsafe-rule: [
s: unsafe-r2-char (
append result to integer! first s
)
]
safe-rule: [
s: safe-r2-char (append result first s)
]
rule: compose/deep [
any [
(either unescape [[escape-rule |]] [])
safe-rule
(either unsafe [[| unsafe-rule]] [])
]
]
unless parse/all str rule [
print "Unsafe codepoints found in string! by r2-string-to-binary"
print "See http://stackoverflow.com/questions/15077974/"
print mold str
throw "Bad codepoint found by r2-string-to-binary"
]
result
]
変換の代わりにこれを使用するto binary!
と、Rebol2 と Rebol3 の両方で一貫した動作が得られます。terrible-workaround
(スタイル文字列のソリューションを効果的に実装します。)