Google计算器中的特殊字符

时间:2012-10-12 21:37:05

标签: unicode terminal google-api osx-mountain-lion calculator

previous question中,我被告知谷歌会对查询传递UTF-8编码的回复。这解决了在通过卷曲传递到我的终端后,不间断空间(A0)混乱的问题。这是通过将卷曲输出管道连接到无线电并转换为UTF-8来解决的。但是,即使有了这个解决方案,我仍然会得到一些奇怪的输出。

考虑以下将2米转换为英尺:

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

2 个答案:

答案 0 :(得分:2)

通过curl访问的Google Calculator正在返回JSON。 Google正在使用\ xHH表示法,因为它是JSON的标准。如果将输出发送到浏览器(或其他任何解析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(&lt;,&gt;和&amp;分别),而-n禁止回音通常会添加的换行符。

sed的管道在所有(上标)标签之前添加一个空格,然后删除所有HTML标签。

perl的管道然后解码所有HTML实体,例如/ to /(split slash)。 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编码)。在十六进制中,这是0xA0或\ xA0,并以UTF-8编码编码到非中断空间,这是谷歌正在传递的。所以在AppleScript中,为了从UTF-8替换非破坏空间,我们必须使用†(匕首),因为Macintosh编码。

sed线还有几个特殊的分数符号: http://tlt.its.psu.edu/suggestions/international/bylanguage/mathchart.html#fractions

故事的寓意是,在处理JSON时,只需使用一个好的JSON解析器。

子道德是:不要使用AppleScript来处理JSON。

答案 1 :(得分:1)

问题Is there an official API for Google calculator?的已接受答案是否定的,因此您似乎只需要尝试对其功能进行反向工程。这里它似乎代表47/64的分数,因此分子47在<sup>标记内,而分母64在<sub>标记内,然后<>具有已使用\xnn表示法进行转义,nn是该字符的十六进制代码。这似乎没有多大意义,因为风格上标和下标毫无意义,在HTML标记中执行它是奇怪的,并且转义标记分隔符很奇怪。然而,主要的问题是,<sup>有时可能意味着上标使表达式成为指数,因此仅删除此类信息可能会使信息失真。