HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0802
ユーヤンUnicodeエスケープシーケンスに変換するには?9解決


ユーヤン

リンク

2021/8/2(Mon) 22:37:33|NO.93450

HSP3でUnicodeエスケープシーケンスでエンコードしたり、出コードすることはできないのでしょうか?
hsp3utf.asをインクルードしている前提でお願いします。



この記事に返信する


ユーヤン

リンク

2021/8/2(Mon) 22:38:23|NO.93451

文字変換ミス
誤:出コード 正:デコード です。



ユーヤン

リンク

2021/8/2(Mon) 22:44:30|NO.93452

↓以下のスクリプトだとなぜか変換されません。

#include "hsp3utf.as" #include "form_decode.as" #include "encode.as" before = "\\u3053\\u3093\\u306b\\u3061\\u306f" // デコードの実行 result = "" form_decode result, before mes result



沢渡

リンク

2021/8/3(Tue) 01:05:45|NO.93453

form_decade.asの内容を読んだ限り、Unicodeエスケープシーケンスには
対応していないようですが。
エスケープシーケンスの仕様についてよく理解していないかもしれませんが、
とりあえず作ってみました。

#include "hsp3utf.as" //←SJISに対応している文字ならこれなしでも表示できる筈 #include "Kernel32.as" #module #define ctype wide(%1) ((%1)*2) //UTF-16は2バイト単位で扱う #defcfunc ucode_esc str _ent sdim ent,strlen(_ent)*2+2 : cnvstow ent,_ent //UTF-16に変換 lstrlenW varptr(ent) : size=stat : sdim buf,wide(size+1) p=0 : p2=0 //それぞれ書き込み元と書き込み先の位置(2バイト単位) repeat if p>=size : break x=wpeek(ent,wide(p)) f1=0 //エスケープシーケンスを出力したフラグ if p<=size-6 { if (x='\\')&((wpeek(ent,wide(p+1))='u')|(wpeek(ent,wide(p+1))='U')) { buf2=0 //出力バッファ f2=0 //出力に失敗したフラグ repeat 4,2 buf2=buf2<<4 y=wpeek(ent,wide(p+cnt)) if (y>='0')&(y<='9') { buf2|=y-'0' } else { if (y>='A')&(y<='F') { buf2|=y-'A'+10 } else { if (y>='a')&(y<='f') { buf2|=y-'a'+10 } else { f2=1 } } } if f2 : break loop if f2=0 { wpoke buf,wide(p2),buf2 p2++ : f1=1 : p+=6 } } } if f1=0 : wpoke buf,wide(p2),x : p++ : p2++ loop return cnvwtos(buf) //UTF-8(もしくはsjis)にして返す //surr_str p1 //p1にUnicodeの番号を指定すると、Unicodeエスケープシーケンスの形で返す #defcfunc surr_str int uni if uni>0xFFFF { //0x10000以上の場合はサロゲートペアの形で return strf("\\u%04x\\u%04x",(((uni-0x10000)>>10)&0x3FF)|0xD800,((uni-0x10000)&0x3FF)|0xDC00) } return strf("\\u%04x",uni) #global font msgothic,32 mes ucode_esc("\\u3053\\u3093\\u306b\\u3061\\u306f"+surr_str(0x1F97A)) //ついでに語尾に「ぴえん」をつけてみる



沢渡

リンク

2021/8/3(Tue) 01:07:07|NO.93454

こちらはUnicode番号の入った整数配列を文字列に変換するタイプです。
どちらか都合の良い方で。

#include "hsp3utf.as" //←SJISに対応している文字ならこれなしでも表示できる筈 //Unicode値を入れた整数配列を文字列に変換して返すモジュール #module #defcfunc ucode2str array ucode size=0 : items=0 //UTF-16バッファの必要なサイズを求める repeat length(ucode) x=ucode(cnt) if x=0 : break items++ : size++ : if x>0xFFFF : size++ //0xFFFF以下の場合は2バイト、0x10000以上の場合は4バイト必要 loop sdim buf,size*2+2 p=0 repeat items x=ucode(cnt) if x>0xFFFF { //0x10000以上の場合は「サロゲートペア」の形にして4バイト書き込む lpoke buf,p,((((x-0x10000)>>10)&0x3FF)|0xD800) | ((((x-0x10000)&0x3FF)|0xDC00)<<16) p+=4 } else { //0xFFFF以下の場合はそのままの形で2バイト書き込む wpoke buf,p,x p+=2 } loop return cnvwtos(buf) //UTF-16からUTF-8(もしくはSJIS)に変換して返す #global font msgothic,32 dim arr,6 arr=0x3053,0x3093,0x306B,0x3061,0x306F,0x1F97A mes ucode2str(arr)



ユーヤン

リンク

2021/8/3(Tue) 17:48:04|NO.93456

おお、スクリプトありがとうございます。やっぱり標準では対応していなかったんですね…。
あと、改行コードも含める場合は、モジュール内の

strrep texts,"\\r\\n","\n" strrep texts,"\\n","\n" strrep texts,"\\r","\r"
を付与すればOKなのでしょうか?

#module #uselib "kernel32.dll" #func lstrlenW "lstrlenW" int #define ctype wide(%1) ((%1)*2) //UTF-16は2バイト単位で扱う #defcfunc ucode_esc str _ent sdim ent,strlen(_ent)*2+2 : cnvstow ent,_ent //UTF-16に変換 lstrlenW varptr(ent) : size=stat : sdim buf,wide(size+1) p=0 : p2=0 //それぞれ書き込み元と書き込み先の位置(2バイト単位) repeat if p>=size : break x=wpeek(ent,wide(p)) f1=0 //エスケープシーケンスを出力したフラグ if p<=size-6 { if (x='\\')&((wpeek(ent,wide(p+1))='u')|(wpeek(ent,wide(p+1))='U')) { buf2=0 //出力バッファ f2=0 //出力に失敗したフラグ repeat 4,2 buf2=buf2<<4 y=wpeek(ent,wide(p+cnt)) if (y>='0')&(y<='9') { buf2|=y-'0' } else { if (y>='A')&(y<='F') { buf2|=y-'A'+10 } else { if (y>='a')&(y<='f') { buf2|=y-'a'+10 } else { f2=1 } } } if f2 : break loop if f2=0 { wpoke buf,wide(p2),buf2 p2++ : f1=1 : p+=6 } } } if f1=0 : wpoke buf,wide(p2),x : p++ : p2++ loop texts = cnvwtos(buf)//UTF-8(もしくはsjis)にして返す strrep texts,"\\r\\n","\n" strrep texts,"\\n","\n" strrep texts,"\\r","\r" return texts //surr_str p1 //p1にUnicodeの番号を指定すると、Unicodeエスケープシーケンスの形で返す #defcfunc surr_str int uni if uni>0xFFFF { //0x10000以上の場合はサロゲートペアの形で return strf("\\u%04x\\u%04x",(((uni-0x10000)>>10)&0x3FF)|0xD800,((uni-0x10000)&0x3FF)|0xDC00) } return strf("\\u%04x",uni) #global



ユーヤン

リンク

2021/8/3(Tue) 17:57:45|NO.93457

ダブルクォーテーションとスラッシュとバックスラッシュを含める場合、

strrep texts,"\\\"","\"" strrep texts,"\\/","/" strrep texts,"\\\\","\\"
を付与すればOKですよね?




沢渡

リンク

2021/8/3(Tue) 18:21:25|NO.93458

そのエスケープシーケンスというのをどういう用途で使うのかよくわからないのですが、
ここで紹介されているようなものでしょうか?
https://www.fenet.jp/java/column/java_beginner/6049/

もし、たとえば「\n」なる文字列が存在するとして、
それを改行コードに変換したいということなら、
それで良いと思いますが。
(先のコードに特にミスがないのであれば、
 『\uもしくは\Uの後に4桁の16進数が連続している』
 という状態になっているのを確認して、
 はじめてUnicodeに変換するようにしていますので)



沢渡

リンク

2021/8/4(Wed) 01:04:46|NO.93461

あ、一応補足ですが、No.93453の
「エスケープシーケンスの仕様についてよく理解していないかもしれませんが」というのは
「私(沢渡)が」ということです。
念のため、付け加えさせてもらいます。



ユーヤン

リンク

2021/8/22(Sun) 13:54:33|NO.93656

Unicodeエスケープシーケンスに変換する方法は分かったので、一応解決にしておきました。



ONION software Copyright 1997-2023(c) All rights reserved.