这两天与第三方接口调试的时候,接口方提供的 API 返回了一个非标准的 JSON 字符串,整个字符串里没有一个双引号,导致不能直接使用 Java 的 JSON.parseObject() 来将字符串直接转换为对象。

字符串如下:

{itemName:血型,itemCode:651,itemSex:9},{itemName:白带常规,itemCode:679,itemSex:2},{itemName:肝功,itemCode:692,itemSex:9},{itemName:身高体重,itemCode:873,itemSex:9},{itemName:妇科检查,itemCode:1059,itemSex:2},{itemName:CRP+血细胞计数五分+异常红细胞形态,itemCode:1119,itemSex:9},{itemName:血常规五分类CRP,itemCode:1121,itemSex:9}

然后接口方这样给我说的:
微信图片编辑_20210422102422.jpg

到这里我就不指望接口方修改返回格式了,而他说的用逗号分隔,想想就知道多复杂,在网上搜了半天,最后找到一个正则的方案,网上给出的正则规则是这样的:

pattern.replaceAll("(\\{|,)([^:]+)", "$1\"$2\"").replaceAll("([^:,\\}]+)(\\}|,)", "\"$1\"$2")

但这个正则有问题,替换完是这样的:

{"itemName":"血型","itemCode":"651","itemSex":"9"},"{itemName":"白带常规","itemCode":"679","itemSex":"2"},"{itemName":"肝功","itemCode":"692","itemSex":"9"},"{itemName":"身高体重","itemCode":"873","itemSex":"9"},"{itemName":"妇科检查","itemCode":"1059","itemSex":"2"},"{itemName":"CRP+血细胞计数五分+异常红细胞形态","itemCode":"1119","itemSex":"9"},"{itemName":"血常规五分类CRP","itemCode":"1121","itemSex":"9"}

替换完的字符串,从第二个开始," 跑到 { 外面来了,于是跟小伙伴交流,小伙伴最后帮我修改了一个正则:

pattern.replaceAll("{(\w+):(.+?),", "{\"$1\":\"$2\",").replaceAll("(\w+):(\d+)", "\"$1\":\"$2\"");

因为Java字符串的 \w 和 \d 需要转义,所以必须这样写:

pattern.replaceAll("{(\\w+):(.+?),", "{\"$1\":\"$2\",").replaceAll("(\\w+):(\\d+)", "\"$1\":\"$2\"");

搞定后,开始测试结果报错:
微信图片_20210422103100.png

小伙伴吐槽辣鸡 Java,没办法,继续网上搜,结果在一篇帖子里的评论里,看到有人说 Java 的字符串里 { 也需要转义,转义后一测试,果然是这样,所以最后的正则变成了这样:

pattern.replaceAll("\\{(\\w+):(.+?),", "{\"$1\":\"$2\",").replaceAll("(\\w+):(\\d+)", "\"$1\":\"$2\"");

替换后字符串变成了正常 JSON 字符串,在群里跟朋友分享了这件事,朋友表示正则很牛逼。

本以为这件事就过去了,第二天看群消息,群里另一个小伙伴分享了一个新的正则:

pattern.replaceAll("(\\w+):(.*?)([,|}])","\"$1\":\"$2\"$3");

测试时正常的,于是好奇正则的工作原理,开始学习正则的使用,翻看了正则的规则 (菜鸟教程 - 正则) 后,大概懂了这个正则工作原理:

三个括号分成了三组,分别匹配 List 里面的每个节点
\w 表示匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
+ 表示匹配前面的子表达式一次或多次。(要匹配 + 字符,使用 \+)
. 表示匹配除换行符 \n 之外的任何单字符。(要匹配 . ,使用 \.)
* 表示匹配前面的子表达式零次或多次。(要匹配 * 字符,使用 \*)。
? 表示匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。(要匹配 ? 字符,使用 \?)
| 表示两项之间的一个选择。(要匹配 |,使用 \|)

正则学会了真的很强大,但这里只了解了一点皮毛,后面还要继续学习。

最后修改:2021 年 05 月 31 日
請我飲一杯咖啡