一次正则引发的加班.md

2022/6/13 杂谈

大家好,我是米洛,一个卷王加班仔。求三连!求关注米洛的测开日记!

正则表达式,一个熟悉又陌生的词汇。说他熟悉,因为刚工作就接触到了。说他陌生,因为我今天翻了车

# 故事

下午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*\\((.+)\\)";
1

可以看出,我用了3个()去分别筛选出3个数据:

  • 表名: 这个紧挨着insert into的数据

  • 字段名: 在表名后面,在()里面

  • 字段值: 在values后面的()里面

    详细解释一下:

    insert + 至少0个空格 + into+至少1个空格 + (表名) + 至少0个空格 (字段名) + 至少0个空格 + values + 至少0个空格 + (字段值)

    注: \\s代表空格

# 找到问题

其实问题很简单,这个正则也存在一个很大的问题: 我用(.+)去匹配表是没问题的,但是在字段之间,有的小可爱是会给你加上换行符号(\n)的,因为正则默认.是无法匹配换行符号的,这就导致(.+)没法匹配到下一行的数据了,从而导致执行失败。

确实,这个没得洗,我才是小可爱(辣鸡)

有人问了,你还有个地方没注意啊,你的insert是小写的,我要是大写的INSERT你也匹配不到哦!其实不然,在Java里面,可以在正则匹配的时候提供一个参数:

没错,就是这个CASE_INSENSITIVE

这个参数代表我忽略大小写,所以我是这样玩的。

# 解决问题

经过我的一番搜索,终于俾我找到了解决方案!那就是正则匹配的时候,是有个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)!!!


关注我,带你了解更多加班知识!👻👻👻所以,你学会了吗?