用于在符号后的行中拆分 JSON 文本的正则表达式

Regular expression for splitting JSON text in lines after symbols

我正在尝试使用正则表达式来获得这种字符串

{
 "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]}]}

我找到了这个用于查找所有逗号的正则表达式。

/(,)(?=(?:[^"]|"[^"]*")*$)/

现在我需要知道:

0-如果这个靠谱,就是说到做到。

1- 如果这也适用于双引号内的逗号。

2- 如果考虑到转义双引号。

3- 如果我还必须考虑单引号,因为这个文件是由我的应用程序生成的,但有时它可以由用户手动编辑。

5- 它必须与多行标志一起使用才能处理多行文本。

6- 它必须与 replaceAll() 一起使用。

生成的正则表达式将用于将每个符号替换为由符号本身加上 \n 字符组成的双字符序列。

生成的文本必须仍然是 JSON 文本。

后续替换操作也将针对其他符号进行

: [ ] { } 

和其他可以在 JSON 文件中找到的引号之间的字母数字序列之外的符号(我不知道提到的符号是否是唯一的)。

它并没有那么简单,但是是的,如果你想这样做,那么你需要过滤字符([{,",',:) 然后用换行符替换它。 喜欢:

[ should get replaced with [\n

你的问题的答案是肯定的,它非常可靠,而且只需一行代码即可实现所有功能。这就是正则表达式的用途。

0- if this is reliable, that is, does what they say.

让我们稍微分解一下表达式:

  • (,) 是匹配单个逗号的捕获组
  • (?=...) 表示正向前瞻,这意味着逗号后面需要跟该组内容的匹配项
  • (?:...)* 将是一个非捕获组,可以出现 0 到多次
  • [^"]|"[^"]*" 将匹配除双引号 ([^"]) 之外的任何字符或 (|) 一对双引号,除了其他双引号 ("[^"]*")

如您所见,如果文本值中存在转义双引号,最后一部分可能会变得不可靠,因此答案将是 "this is reliable if the input is simple enough".

1- if this is works also with commas inside double-quotes.

如果双引号对被正确识别,则其间的任何逗号都将被忽略。

2- if this takes into account escaped double-quotes.

这是主要问题之一:需要处理转义双引号。如果您想处理任意情况,这可能会变得非常复杂,尤其是当文本也可以包含逗号时。

3- if I have to take into account also single quotes, as this file is produced by my app but occasionally it could be manually edited by the user.

JSON 规范不允许使用单引号,但许多解析器都支持它们,因为人们无论如何都倾向于使用它们。因此,您可能需要将它们考虑在内,而这不会。 2 更复杂,因为现在单引号文本中可能有未转义的双引号。

5- It has to be used with the multi-line flag to work with multi-line text.

我对此不是很确定,但添加多行标志应该不会有什么坏处。不过,您可以将它添加到表达式本身,即通过预先设置 (?m).

6- It has to work with replaceAll().

在其当前形式中,正则表达式可以与 String#replaceAll() 一起使用,因为它只匹配逗号 - 前瞻用于确定匹配但不会导致错误部分被替换。如上所述,匹配本身可能不正确。

话虽如此,您应该注意到 JSON is not a regular language and only regular languages 非常适合正则表达式。

因此我建议使用适当的 JSON 解析器(那里有很多)将 JSON 解析为 POJO(可能只是一堆通用的 JsonObject 和 JsonArray 实例) 并根据您的需要重新格式化。

这里有一个如何使用 Jackson 来实现这一点的例子:https://kodejava.org/how-to-pretty-print-json-string-using-jackson/

事实上,由于您已经在使用 JSONObject.toString(),您可能不需要解析器本身,而只需要一个合适的格式化程序(如果您 want/need 自己动手,您可以看看在 org.json.JSONObject sources ).