Java 例程,用于在符号处将 JSON 文本拆分为行



假设我的应用必须以这种形式创建一个 JSON 文本文件

{
"key1"
:
"value1"
,
"key2"
:
"value2"
,
"arrayKey"
:
[
{
"keyA"
:
"valueA"
,
"keyB"
:
"valueB"
,
"keyC"
:
[
0
,
1
,
2
]
}
]
}

JSONObject.toString()

这是我的Android Java应用程序中的一长行文本

{"key1":"value1","key2":"value2","arrayKey":[{"keyA":"valueA","keyB":"valueB","keyC":[0,1,2]}]}

事实证明,正则表达式方法不起作用。

有很多陷阱。

所以我决定创建自己的解析器来完成工作

编辑:注意!以下代码中存在错误,导致转义引号被视为正常引号,请参阅我对此问题的回答(也有进一步改进)

public static String JSONTextToCRSeparatedJSONText(String JSONText)
{
String result="";
String symbolList="{}[]:,";
char ch;
char previousChar=0;
int charNum=JSONText.length();
boolean inRegion=false;
boolean insertedBefore=false;
char startRegionChar=0;
for (int i=0;i<charNum;i++)
{
ch=JSONText.charAt(i);
previousChar=ch; // mistake here, should be after the conditional statements, please see my answer with new code version

if (!inRegion) 
{
if (((ch=='"')||(ch=='''))&&(previousChar!='\'))
{
inRegion=true;
startRegionChar=ch;
}
} else
{
if ((ch==startRegionChar)&&(previousChar!='\'))
{
inRegion=false;
}
}
if ((!inRegion)&& (symbolList.indexOf(ch)>-1)&&(!insertedBefore))
{
result=result+"n";
} 
result=result+ch;
insertedBefore=false; 
if ((!inRegion)&& (symbolList.indexOf(ch)>-1))
{
result=result+"n";
insertedBefore=true; //it will be useful next iteration
}
}
return result;
}

它似乎正在工作。

只是我想知道

如果它检查以插入 控制字符的符号是 JSON 文本中可能的所有符号

如果有一些我看不到的陷阱。

我认为你自己做的工作太多了。今天,有 2 个主要的已知库用于使用 JSON。一个是Jackson-JSON(也称为"Fast XML" - go figure...),另一个是GSON - 一个基于Jackson-JSON的Google库,但也支持传递二进制对象。我个人更喜欢Jackson-JSON,但这是个人喜好的问题。对于 GSON 库,请看这里。对于杰克逊,请看这里。对于杰克逊的Maven文物,请看这里。如果您选择使用 Jackson,那么您需要的主类是 ObjectMapper。 从研究方法开始readValue()writeValue().在网络上寻找有关如何使用它的无穷无尽的例子。这应该给你一个良好的开端。

无论如何,这两个库都允许您生成格式良好的 JSON。对于 Gson:

String content = new String(Files.readAllBytes(resource.toPath()));
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(content);
String prettyJsonString = gson.toJson(je);
System.out.println(prettyJsonString);
return prettyJsonString;

对于 Jackson-JSON:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String prettyJsonString = mapper.writeValueAsString(content);
return prettyJsonString;

通过比你所做的工作少得多,并且经过更好的测试。另外,如果您想在 HTML 中呈现相同的格式,请参阅此问题的答案: JAVA 中 JSON 的漂亮打印适用于控制台,但在浏览器中它不起作用

问题中的代码是错误的,因为

previousChar=ch;

将是当前字符,而不是前一个字符,因此必须将其放在条件语句之后。

正确的代码如下(此外,它经过简化并且不会产生不需要的行):

public static String JSONTextToLineSeparatedJSONText(String JSONText)
{
String result="";
String symbolList="{}[]:,";
char ch;
char previousChar=0;
int charNum=JSONText.length();
boolean inRegion=false;
boolean insertedBefore=false;
char startRegionChar=0;
for (int i=0;i<charNum;i++)
{
ch=JSONText.charAt(i);

if (!inRegion) 
{
if (((ch=='"')||(ch=='''))&&(previousChar!='\'))
{
inRegion=true;
startRegionChar=ch;
}
} else
{
if ((ch==startRegionChar)&&(previousChar!='\'))
{
inRegion=false;
}
}
previousChar=ch; 
if ((!inRegion)&& (symbolList.indexOf(ch)>-1)&&(!insertedBefore))
{
if (i>0) result=result+"n";
} 
result=result+ch;
insertedBefore=false; 
if ((!inRegion)&& (symbolList.indexOf(ch)>-1))
{
result=result+"n";
insertedBefore=true; //it will be useful next iteration
}
}
return result;
}

最新更新