- blogs:
- cles::blog

JSON と 日本語と PowerShell




ちょっとしたデータ保存に JSON を使おうと思って JSON をいじくり回していたのですが、いろいろなデータを入れていくうちに、日本語が \u#### でエスケープされていることに気づきました。この辺は PHP の json_encode()*1 や Ruby の gem json*2 でも全く同じ挙動のようです。
普段、英数字しか入れてなかったのでよく理解していなかったのですが、そういえばTwitter の全発言アーカイブをダウンロードしたときは確かエンコードされていたような気もします。そんわなけで、ちょっとJSON の仕様*3*4を紐解いてみると、文字は Unicode に従うと書いてありますが、エンコードの種類は指定されていないようなので、UTF-8, UTF-16 などいろいろなエンコードが許容されるようです。もちろん \u#### も許容されています。
もちろんどちらも元に戻るので、PHP <-> Ruby 間で相互運用性に問題が生じることはありません。
これをちょっと Windows 上でもお手軽にやろうと思って PowerShell での処理に挑戦してみました。
† ひとまずデコードは問題なし
PowerShell にもバージョン 3.0 から ConvertFrom-Json*5、ConvertTo-Json*6が使えるようになりました。Windows 8 に標準添付の PowerShell は 4.0 ですが、手元の 7 は 2.0 だったので最近のマシンでないと使うことができないのはネックといえばネックかもしれません。リファレンスにも注釈が入っていますが、この昨日は内部的には .NET Framework の JavaScriptSerializer*7 によって実現されているようです。
まずはデコード側を検証。ConvertFrom-JSON は問題なく値を読み取ることができました。
† エンコードするとエスケープされない!!
同様にエンコードも ConvertTo-JSON を使えば楽勝か?と思いましたが、一筋縄ではいきませんでした。
なんと、エンコードされていません。しかもこの出力をリダイレクトすると UTF-16 になります。
ちょっと PowerShell だけ挙動が違うのも困るので、これを何とかすることにしました。まず日本語を \u#### にエスケープする関数を作ります。幸いにも String を HEX に変換するプログラムを見つけた*8ので、今回はこれを元に下記のような関数を書きました。
PowerShell をちゃんと書くのは初めてですが -gt とか書くとシェルスクリプトっぽいですね。こんな感じでしょうか。最後に \\u -> \u という置換をかけていますが、これは ConvertTo-JSON が \ をさらにエスケープしてしまうのを防ぐためです。ちょっといい加減ですが、これでなんとか PHP や Ruby と同じような出力を得ることができました。
さらに、エスケープされていない JSON を Windows 上で手軽にエンコードされた形式に変換できるワンライナーがあると便利かなと思って、ワンライナー化してみました。ワンライナーといえない程、汚くて長いですが、ちょっとした変換用途くらいには耐えられると思います。
JSON なかなか奥深いですね。
- *1: PHP: json_encode - Manual
- *2: json | RubyGems.org | your community gem host
- *3: JSON の紹介
- *4: Final draft of the TC39 “The JSON Data Interchange Format” standard - ECMA-404.pdf
- *5: ConvertFrom-Json
- *6: ConvertTo-Json
- *7: JavaScriptSerializer Class (System.Web.Script.Serialization)
- *8: Powershell - string to HEX (or whatever you like)
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/6786
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110676)
3 . 年次の人間ドックへ(110302)
4 . 2023 年分の確定申告完了!(1つめ)(109845)
5 . 三菱鉛筆がラミーを買収(109746)