dlang

TwitterのJSONを解析する

More than 3 years have passed since last update.

TwitterのJSONには一部Unicodeではない(?)文字が混じっていることがあるらしく、これがD言語のstd.json.parseJSONで解析に失敗する原因となる。

std.json.parseJSONには、このような文字列に出会った時に置換したりするようなインターフェースは残念ながら備わっていない。(std.csvには備わっていて、例外を投げるか無視するかを選択可能)

そのため、予めこれらの文字列を何かしらに置換する必要がある。

今回はstd.jsonはある程度解析に時間がかかるモジュールであると割りきって、regexを使って置換を試みることにした。

import std.json, std.utf, std.regex, std.uni, std.ascii;

JSONValue toJSONValue(string contents)
{
enum r = ctRegex!r"\\u([0-9a-fA-F]{4})";
string func(Captures!string c)
{
dchar val = 0;
char[4] buf = void;
auto str = c[1].toUpper();
foreach (i, ch; str)
val += (isDigit(ch) ? ch - '0' : ch - ('A' - 10)) << (4 * (3-i));
return isValidDchar(val) ? toUTF8(buf, val).idup : "□";
}
return contents.replaceAll!func(r).parseJSON();
}

上記のように無効文字を置換するようにしてやることで、解析を行う事ができる。