正则匹配json字符串中的key,将kebab-case转换为camelCase

项目中遇到处理接口返回json的需求:
将json键中的kebab-case转换为camelCase

为解决需求进行了一系列学习,在此记录学习过程。

首先了解几种case:


命名法


  1. camelCase 驼峰命名(lowerCamelCase)
  2. snake_case 蛇形命名
  3. kebab-case 短横线命名
  4. PascalCase 帕斯卡命名(UpperCamelCase)



正则表达式

匹配json中的key


由于觉得以JSONObject形式添一个键值对再删一个键值对的操作,不是很合理,相当于所有键为一个单词以上的键值对都重新添加,如果数据量很大…
于是想直接处理字符串,便有了一晚上的琢磨(ŏ_ŏ),总算被我试出来了

先把最终匹配到所有键的正则表达式放在这里( 对于我使用的json数据是完全正确的,如果有遗漏的情况欢迎指点 ):

// by Sheri
// jdk8
String regex = "\"(.+?)\":.*?(?=[,{}])\"?";
// String json = "(a json string)";
Matcher m = Pattern.compile(regex).matcher(json);
// match到所有的键

while(m.find()){
        if(m.group(1).contains("-")){
                 // more than one word
                 // 进行kebab-case到camelCase的转换
        }
}

命名法转换


起初想直接替换,jdk11中已有replaceAll的第二种调用方式,可以使用lamda表达式直接写好转换逻辑作为参数传入:

// jdk11
String s = Pattern.compile("-([a-z])")
                             .matcher(json)
                             .replaceAll(matchResult 
                             -> matchResult.group(1)
                            .toUpperCase());

但是由于项目某处的import,需要使用jdk8环境,没有这一个重载的方法,并且Matcher的操作有种种限制,我可能没有以最简洁的方式解决这个问题,但为了寻找能够正确完成需求的方法,我算是对Matcher进行了一番研究

解决问题流水账:

——试图直接用

m.replaceAll(m.group(1).toUpperCase())
  • 存在问题:由于要保证修改的是键不是值,所以第一层的matcher匹配的是完整的键字符串。如果一个键由三个或以上单词组成,即会出现两个或以上的"-"(hyphen),此时matcher的region会是整个key字符串,而上述replaceAll则会同时将所有"-[a-z]“替换成第一个”-[a-z]"的大写。
  • 例如:last-return-date 替换成 lastReturnRate,而本该依次m.find()去转换才能避免该问题。

——借助StringBuffer修改非预期的命名法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值