LoginSignup
6
4

More than 5 years have passed since last update.

FBXを経由したときに化けちゃった日本語文字列をなんとかする

Posted at

なにげに前回(▼)の続きです。

シーン内に日本語名がついたオブジェクトがあるとき、
FBXで渡すと下記のようなオブジェクト名に変換されてしまいます。

FBXASC229FBXASC137FBXASC141FBXASC233FBXASC171FBXASC1702

oh! Fxxk!!

マテリアルやテクスチャ、ブレンドターゲットなんかも同様になりますので、
かなりいっぱいこういうのが錬成されます。

なんとかしたい

以下のようにしてみました。

from binascii import a2b_hex as a2b

def fbxasc_to_chr( target_str ):
    return_list = []

    stock = ''
    for var in target_str.split( 'FBXASC' ):
        # 空だったら無視する
        if not var:
            continue
        # 1文字目がアルファベットだったら対象外 return_listに足して次へ。
        if var[0].isalpha():
            return_list.append(var)
            continue

        # 字数が3より多ければ、3文字目までをint変換
        ex_digit = ''
        if len(var)>3:
            ex_digit = var[3:]
            code_int = int(var[:3])
        else:
            code_int = int(var)

        stock +=hex( code_int )
        try:
            return_list.append( a2b(stock.replace('0x','')).decode('utf8') )
        except UnicodeDecodeError:
            continue

        # decode、appendができたらリセット
        stock = ''

        if ex_digit:
            return_list.append(ex_digit)

    return ''.join(return_list)

ふんわり解説

ファッキンFBX文字列をみてみると、「FBXASC」というのが定期的に入っていることが観察できます

もっというと

FBXASC + 0-255

の組み合わせです。
これを一つの単位(1バイト)として、いくつか並んだ時に文字としてデコードできます。
いくつかというのは、1つで成立するときもあるし、3つで成立するときもあるということです。
なかなかにややこしいので詳細はUTF-8の解説@wikipediaにお任せしますが
https://ja.wikipedia.org/wiki/UTF-8#.E6.96.87.E5.AD.97.E7.A8.AE
(▲)この表によると、英数記号は1、「東アジアの諸文字・全角」は3、なようです。
第3・第4水準の漢字の一部は4とありますね。

hex

0-255のままでは使えませんので、16進数に直します。
これが冒頭でも言及した、前回の記事です。hex関数を使うことにしました。

変換後には必ず0xがつきますが、これを、アスキーからバイナリに変換する前にまとめて除去しています。

〜〜.replace('0x','')

アスキー -> バイナリ変換

ここまででは、まだ「 0-9a-f でできた文字列」です。
これをバイナリに変換します。
binasciiモジュールa2b_hex関数を使います。

アスキー -> バイナリ変換後は decodeメソッド が使えますが、存在しない番地だとデコードエラーが発生します。
このエラーを拾って、もしデコードエラーが起きるようなら次に持ち越し、連結して再度変換、という流れになっています。

FBXASC化されてない愉快な仲間たちへの対処

文字列全部が「FBXASC+0-255」になってくれていれば話は早いのですが……

例えば「.」は「FBXASC046」に書き換えられて登場するのですが、
普通の英数は英数のまま文字列に混ざってきます。
なので、単純にFBXASCでsplitしただけだと、得られるリストの中に「4桁の数値(0-255の幅じゃなくなってしまう)」や、「3桁+英文字(hexに渡す前にint変換できない)」が含まれてしまいます。
はみ出た桁はex_digit という変数に入れてあとから連結することにしました。

またオブジェクト名が英数字で始まる/終わる場合は、FBXASCでsplitされない要素が最初/最後にどれくらいつくかわかりませんので、なんかそれっぽくなるようifで仕分けします('A`)

結果、なんかもっとあるだろという気がしてなりません(笑

あと今気づいたんですが、これだともとから0-255の数字が含まれていた場合逆に化けちゃうのじゃないかという謎の心配がありますー疲れたのでまいいや:wink::wink::wink:

まとめ

シーン内に日本語を含めた車輌は全員シベリア送り25ルーブルよ!

参考

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4