2

以前の質問で、Google は UTF-8 でエンコードされた応答をクエリに渡すと言われました。これにより、非改行スペース (A0) が curl によって端末に渡された後に混乱する問題が解決されました。これは、curl 出力を inconv にパイプして UTF-8 に変換することで解決されました。ただし、このソリューションを使用しても、まだ奇妙な出力が得られます。

次の 2 m からフィートへの変換を検討してください。

http://www.google.com/ig/calculator?hl=en&q=2%20m%20in%20feet

これは、ブラウザやその他の場所で表示される出力です。

{lhs: "2 meters",rhs: "6.56167979 feet (6 feet 6\x3csup\x3e47\x3c/sup\x3e\x26#8260;\x3csub\x3e64\x3c/sub\x3e inches)",error: "",icc: false}

予想される出力は次のとおりです。

{lhs: "2 meters",rhs: "6.56167979 feet (6 feet 6 47/64 inches)",error: "",icc: false}

正規表現またはその他のソリューションを使用してテキストを置換することもできますが、ここで何が起こっているのか知りたいです。洞察はありますか?

Mac OS X Mountain Lion 10.8.2 を実行しています

4

2 に答える 2

2

curl 経由でアクセスした Google Calculator は JSON を返します。Google では、JSON の標準である \xHH 表記を使用しています。出力が標準出力ではなくブラウザー (または HTML を解析するその他のもの) に送信される場合は、優れた JSON デコーダーのみが必要になります。

JSON を解析するためにコマンドラインから何ができるか見てみましょう。

echo -en $(curl -s 'http://www.google.com/ig/calculator?hl=en&q=4^22') > ~/temp.html

これにより、ブラウザ経由で表示できる有効な HTML が得られますが、すべてを標準出力経由で表示できるものに縮小する必要があります。

echo -en "$(curl -s --connect-timeout 10 "http://www.google.com/ig/calculator?hl=en&q=2%20m%20in%20feet")" | sed -e 's/<sup>/ &/g' -e :a -e 's/<[^>]*>//g;/</N;//ba' | perl -MHTML::Entities -ne 'print decode_entities($_)' | iconv -f ISO-8859-1 -t UTF-8

echo コマンドの場合、-e は \x3e、\x3c、および \x26 (それぞれ <、>、および &) などのエスケープを解釈しますが、-n は echo が通常追加する改行を抑制します。

sed へのパイプは、すべての (上付き) タグの前にスペースを追加してから、すべての HTML タグを削除します。

次に、perl へのパイプは、⁄ から ⁄ (分数スラッシュ) などのすべての HTML エンティティをデコードします。 http://en.wikipedia.org/wiki/Html_special_characters#Character_entity_references_in_HTML

iconv へのパイプは、ISO-8859-1 出力を予想される UTF-8 に変換します。perl 行は適切に変換する必要がある UTF-8 エンティティを生成する可能性があるため、これは最後に行われます。

これには、分数と指数を区別する際にまだ問題があります (47/64 では 47 が上付きタグでラップされ、64 は下付きタグでラップされ、10^13 では 13 が上付きタグでラップされます)。

非常にばかげて、非常に長い sed 行を作成して、すべての特殊文字を解析することができます (以下は AppleScript で書かれているため、構文がいかにばかげているかがわかります)。

set jsonResponse to do shell script "curl " & queryURL & " | sed -e 's/[†]/,/g' -e 's/\\\\x26#215;/*/g' -e 's/\\\\x26#188;/ 1\\/4/g' -e 's/\\\\x26#189;/ 1\\/2/g' -e 's/\\\\x26#190;/ 3\\/4/g' -e 's/\\\\x26#8539;/ 1\\/8/g' -e 's/\\\\x26#8540;/ 3\\/8/g' -e 's/\\\\x26#8541;/ 5\\/8/g' -e 's/\\\\x26#8542;/ 7\\/8/g' -e 's/\\\\x3csup\\\\x3e\\([0-9]*\\)\\\\x3c\\/sup\\\\x3e\\\\x26#8260;\\\\x3csub\\\\x3e\\([0-9]*\\)\\\\x3c\\/sub\\\\x3e/ \\1\\/\\2/g' -e 's/\\\\x3csup\\\\x3e\\([0-9]*\\)\\\\x3c\\/sup\\\\x3e/^\\1/' -e 's/( /(/g'"

† (ダガー) 文字は、MacRoman セット (Macintosh エンコーディング) 内では 10 進数で 160 です。16 進数では、これは 0xA0 または \xA0 であり、Google が渡している UTF-8 エンコーディングの Non-Breaking Space にエンコードされます。そのため、AppleScript では、非改行スペースを UTF-8 から置き換えるには、Macintosh エンコーディングのために † (短剣) を使用する必要があります。

sed行が扱う特別な分数記号もいくつかあります。

この話の教訓は、JSON を扱うときは、優れた JSON パーサーを使用することです。

サブモラルは、AppleScript を使用して JSON を処理しないことです。

于 2012-10-15T18:13:07.750 に答える
1

質問に対する受け入れられた回答Google 電卓の公式 API はありますか? は否定的であるため、その機能をリバース エンジニアリングする必要があるようです。<sup>ここでは、分子 47 がマークアップ内にあり、分母 64 がマークアップ<sub>内にあるように、分数 47/64 を表しているよう<に見え>ます。文体上の上付き文字と下付き文字は無意味であり、HTML マークアップでそれを行うのは奇妙であり、タグ区切り文字をエスケープするのは奇妙であるため、これはあまり意味がないようです。ただし、主な問題は、時々、\xnnnn<sup>式を指数にするために上付き文字を使用することを意味する可能性があるため、そのような情報を削除するだけで情報が歪む可能性があります。

于 2012-10-12T22:33:11.417 に答える