Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

シーン内に日本語名がついたオブジェクトがあるとき、
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ルーブルよ!

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした