大家好,我是米洛,一个
卷王加班仔
。求三连!求关注米洛的测开日记
!
正则表达式,一个熟悉又陌生的词汇
。说他熟悉,因为刚工作就接触到了。说他陌生,因为我今天翻了车
。
# 故事
下午6点,在我打算去吃完饭的前一秒,我的老板
跟我发来一条消息:
我心里想,这有嘛,给我不分分钟搞定吗?还是先吃饭
要紧!在干完一大碗水饺后,我回到了座位上,开始调试这条SQL。
可能有人会问了,为什么我要解析SQL,这个不是SQL解释器
做的事情吗,你来凑什么热闹!
其实是这样的,开发提供了一款cud(增删改)的接口,主要是针对一些分库分表的数据,只要告诉他,你要改什么字段,主键是啥,分分钟完成: shard + cud
的操作,比较方便。但唯一的缺点就是,咱们测试如果写SQL,需要把SQL给转换为JSON请求体。
第一是转换过程比较麻烦,第二是大家也都习惯写SQL语句
了。
但作为团队提效小能手
的我,便提供了这样一款工具。可以让他们在页面上写SQL,我在暗处悄悄给转为json请求体
,并发送给开发的接口,合着我就是一中间人。
其实核心原理就是通过正则表达式
去处理用户输入的SQL,拼凑出想要的数据。
# 之前的正则(可以留言吐槽我写的烂)
因为整个项目都是用Java编写,所以本文以Java为主,但是结尾有Python解法。
先来看看我之前写的sql,匹配insert
操作的:
String insert = "insert\\s*into\\s+(.+)\\s*\\((.+)\\)\\s*values\\s*\\((.+)\\)";
可以看出,我用了3个()去分别筛选出3个数据:
表名: 这个紧挨着
insert into
的数据字段名: 在表名后面,在()里面
字段值: 在values后面的()里面
详细解释一下:
insert + 至少0个空格 + into+至少1个空格 + (
表名
) + 至少0个空格 (字段名
) + 至少0个空格 + values + 至少0个空格 + (字段值
)注:
\\s代表空格
# 找到问题
其实问题很简单,这个正则也存在一个很大的问题: 我用(.+)
去匹配表是没问题的,但是在字段之间,有的小可爱
是会给你加上换行符号(\n)的,因为正则默认.是无法匹配换行符号
的,这就导致(.+)没法匹配到下一行的数据了,从而导致执行失败。
确实,这个没得洗,我才是小可爱(辣鸡)
。
有人问了,你还有个地方没注意啊,你的insert是小写的,我要是大写的INSERT
你也匹配不到哦!其实不然,在Java里面,可以在正则匹配的时候提供一个参数:
这个参数代表我忽略大小写
,所以我是这样玩的。
# 解决问题
经过我的一番搜索,终于俾我找到了解决方案
!那就是正则匹配的时候,是有个dotall
的选项的,注意这个选项不只是Java里面有哦。于是我找Pattern的参数,果然有个DOTALL变量:
但是这样我的大小写
就没法生效了,愁人!因为它只接受一个参数
!!!
那么有没有两全其美
的办法呢?
其实是有的,只要多搜一搜就会找到:
有个哥们又想匹配特殊符号,又想忽略大小写,所以对我们来说也适用,于是我们可以这么写:
不知道小伙伴们,你们知不知道正则的这些特点呢?
.
不能匹配换行符号- 正则在匹配时可以忽略大小写
- 可以让
.
匹配换行符号
# Python里面怎么做呢?
毕竟咱们确实还是Python
博主,I write Java, But I love Python!
不得不说,正则还是太强大了,各个语言都有对应的实现:
SQL语句:
insert into ceshikaifaganhuo (name, \nowner, \nage) VAlues ('wang', 'wangz', 2);
正则表达式:
insert[\s|\r|\n]*into[\s|\r|\n]*(.+)[\s|\r|\n]*\((.+)\)[\s|\r|\n]*values[\s|\r|\n]*\((.+)\)
可以看到不管是单纯的DOTALL还是单纯的IGNORECASE都无法取到结果,但是Python我类比了一下,果然也可以通过|
去同时传递2个参数,最终拿下(加班2小时的offer)!!!
关注我,带你了解更多加班知识
!👻👻👻所以,你学会了吗?