前言
很久没写文章了,今年由于种种原因年初休息了两个月,后面又由于今年的环境被休息了两个月,端午节过后终于开始上班了,只是这个班比想象中要忙很多。趁着晚上这会儿不想撸代码,便把最近撸代码时的一些正则的心得记录下来。
案例
xml 标签转 bean 属性(使用正则)
闲话少说,正则的强大之处前面已经介绍过了,这里就不在赘述。只是最近工作中的一些场景,突发奇想发现使用正则可以大大减轻重复工作量。
场景如下,最近对接的系统需要用到 xml
解析,由于原来系统内部都是 json
交互的,为了适配需要把接收到的 xml
报文转换为 bean
,业务完成以后需要把对应的数据转换为 xml
返回。
例如,需要把下面的 xml
报文转换为 bean
对象:
<?xml version="1.0" encoding="UTF-8"?>
<Root><Head><SvcId>007</SvcId><SvcCode>01</SvcCode><IpAddress>127.0.0.1</IpAddress><MacAddress>FD-RF-EF-IU</MacAddress></Head><Body><Name>张三</Name><Age>18</Age><Class>三年级一班</Class>......</Body>
</Root>
当然,这里只是一个实例,实际的业务数据肯定比这个多很多,我们需要把业务数据也就是<Body></Body>
标签中的数据解析为 bean
对象。通常,为了方便,我们一般会使 bean
对象的属性与标签保持一致。所以这就是一个体力活:
public class ServiceEntity{private String name;private String age;......
}
一个一个标签拷贝过来改个首字母大小写贴进去就可以了,我第一个也是这样通过 CTRL+C
、CTRL+V
完成的,这也没什么不好,毕竟大家都是这样做的。只是看到第二个 body
标签里有将近上百的属性时…
于是我就想这玩意还有没有简单一点的办法,于是就想到了使用正则,一实验发现比想象的要简单和好用。
例如,要将下面的标签转换为 bean
属性:
<Name>张三</Name>
<Age>18</Age>
<Class>三年级一班</Class>
......
只需要一个简单的查找替换即可完成:
# 查找正则
^<(\w)(\w*)>.*# 替换正则
private String \L$1\E$2;\r\n
于是,替换完成之后就变成了这样:
private String name;private String age;private String class;
于是这需要一个CTRL C V
即可完成,当然字段类型可能部分需要调整。常用的编辑器例如 notepad++
、editPlus
、idea
等工具都支持正则替换。
前面 xml
转 bean
已经通过这种偷懒的方式完成了,我们还需要把结果转换为 xml
,这里我们用到了 freemarker
,所以就需要定义模版。
bean 属性转 xml 标签(使用正则)
有了前面的经验,我们需要把对应的 bean
转换为 ftl
模板也就不那么难了,直接上例子,还是以前面的例子为基础,这次我们需要把对应的属性转换为对应的 xml
标签,正则来了:
# 查找正则
^\w+\s+\w+\s+(\w)(\w*);# 替换正则
<\U$1\E$2>${$1$2}<\U$1\E$2>
于是,上面的属性就变成了这个样子,
<Name>${name}<Name><Age>${age}<Age><Class>${class}<Class>
当然,也可以把他们之前的空行去掉:
^\w+\s+\w+\s+(\w)(\w*);\r\n
very good,如果有大量这种重复工作,通过这种方式还是可以减少不少工作量的。
当然,正则有些时候也不是万能的,比如最近遇到的一个需求,需要把xml
报文头的内容提取到 bean
中,结果我们写了一个常常的正则出来,一共需要提取 20 多个字段,需求是满足了,但是我测试了下发现效率非常低,一次解析需要100+毫秒,这个速度是不能接受的。最后经过测试我发现如果一次只提取四五个字段,使用这种方式还是很快的,解析一次用时不到一毫秒,基于以上发现,我把上面长长的正则分解为五段,对5分分别解析,最后测试发现使用这种方式完全可以把解析时间控制在3毫秒以后,这个速度是可以接受的。
结语
所以,正则很强大,但是正则不是万能。在适合的场景还是很好用的。今天的分享就到这里,感谢您的阅读,如果不足之处,欢迎指正。