【问题标题】:Detecting and parsing escape character "\" from a JSON File?从 JSON 文件中检测和解析转义字符“\”?
【发布时间】:2012-06-16 18:35:17
【问题描述】:

我在处理 JSON 文件的数据时遇到问题。我正在使用来自 google 的以下链接。

http://www.google.com/finance/company_news?q=AAPL&output=json"

当我想解析数据并将其放在屏幕上时,就会出现我的问题。由于某种原因,数据没有被正确解码。

原始数据:

 1.) one which must have set many of the company\x26#39;s board on the edge of their
 2.) Making Less Money From Next \x3cb\x3e...\x3c/b\x3e

当我引入数据时,我会执行以下操作:

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();        
BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8); 
StringBuilder sb = new StringBuilder();
String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "n");
}
is.close();
json = sb.toString();

我收到的输出,使用 org.json 从 json 文件中提取数据,如下(注意缺少反斜杠):

1.)one which must have set many of the companyx26#39;s board on the edge of their
2.)Making Less Money From Next x3cbx3e...x3c/bx3e

我目前处理第一个问题的方法是:

JSONRowData.setJTitle((Html.fromHtml((article.getString(TAG_TITLE).replaceAll("x26", "&")))).toString());

第二个逃过我(没有双关语)

我认为这不起作用的原因是反冲用于转义字符。我尝试了许多不同的方法来读取数据,但我没有运气。有没有办法在不使用正则表达式的情况下导入数据来处理这个问题?


解决方案

我们今天的克星:“\​​x26”——ASCII(十六进制)

将原始数据读入一个字符数组。来自 apache 的 commons.io 库是一个很好的方法。完成此操作后,在 for 循环中读取 char 数组以查找“\”,如果命中则在下一个数组位置查找“x”。如果再次命中,则取 char 数组中的下两个字符。这两个字符是您的 ASCII 十六进制值。将十六进制转换为十进制形式,然后将十进制转换为字符。获取此字符并将其附加到字符串生成器。

如果没有匹配(带有“\”),则将字符附加到字符串生成器。我们现在可以调用.toString() 方法并将其转换为字符串。

从那里,数据可能包含一些 HTML 残余(在这种情况下是'和/或 )。使用 Html.fromHtml() 处理了这个。

【问题讨论】:

  • this。而且,您是否尝试过逃避转义字符? (如第二个答案所建议)
  • @Keyser 我之前确实注意到了该链接,但它没有提供可行的解决方案。我可以逃脱逃脱,但这不需要使用正则表达式将“\”替换为“\\”吗?
  • 答案如下,以及答案的cmets中解决此问题的方法的描述
  • 让我想起了很多链接:p 太糟糕了,没有更好的解决方案。

标签: java android json


【解决方案1】:

这里的问题是谷歌——或者至少那个网址——是supplying invalid JSON1,2。 JSON 库虽然没有直接拒绝无效的 JSON,但正在以“好吧,让我们忽略这个\废话并继续”的方式对其进行解析。也就是说,不是rendering错了,而是input错了。

1不允许\x 出现在字符串中(除了,如果\ 本身已转义)为\(未转义时)后面只能跟一小组字符(不包括x)。字符代码的转义必须由\u1234 而不是\x12 完成。

我能想到的唯一“修复”是非常严重的黑客攻击:即阅读原始文本并将\x12 转换为\u0012。 (实际上,黑客攻击并没有那么糟糕,因为不需要考虑上下文相关的东西;但是,它应该是必需的!在 Google 上感到羞耻。)

2 提取的无效 JSON 字符串文字:

“Apple Inc.(纳斯达克股票代码:AAPL)的股票在今年的表现中继续领跑大型科技股。在周一开始的关键事件之后,该股的价格没有出现重大变动。”

(要使其有效,请将\x26 替换为\u0026&。)

编码愉快,祝你好运:)


在 Java 中,一种 [未经测试] 的方法可能是使用正则表达式(通过 String.replaceAll):

inputString.replaceAll("\\x(\d{2})", "\\u00$1") 

【讨论】:

  • 我害怕这一点,我的一厢情愿总是占上风。我会尝试处理原始数据,也许我可以从那里解决。我可以将输入作为 XML 获取,但随后数据被包裹并嵌套在各种 HTML 标记中,并且一团糟。感谢您的回复,我也会尝试从 Google 开发人员那里获得答案。
  • @wdziemia 实际上,那个 JSON 是各种损坏的。我跳到问题中,但键也是 不是 JSON 字符串,因此是无效的......看起来有人生成了“JavaScript 对象文字”和 not JSON .我会尽量不去想它,因为它让我头疼:由一家引入了 ProtocolBuffers 的知名 IT 公司(据传其中充满了非常聪明的人)提供的服务......
  • 搞定了,感谢您的帮助!将原始数据读入字符数组,然后将十六进制表示法中的 ASCII 字符替换为其尊重的十进制值。然后将十进制值转换为字符。 Html.fromHtml() 把剩下的任何 HTML 实体代码/HTML 标记拿走。再次感谢!
  • @wdziemia 很高兴你找到了答案。但是,我可能会尝试使用字符串而不是字符数组。我已经用小 [未经测试] 示例更新了我的帖子,它可能也可以工作......
  • 这很有趣。我刚刚访问了链接,但密钥仍然没有引用,可能还有许多其他问题。你们没有人报告这个吗?正确获取 JSON 非常容易。我会报告它......明天......也许
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2014-05-08
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
相关资源
最近更新 更多