实际场景1 - WITH临时表的拆分
因为公司发展需要,要对sql进行改造拼装,借此需要一些比较奇葩的正则表达式来处理。
由于公司采用的是基于Presto的阿里收费平台ADB,所以一下以ADB语法作为讲解。
假设有一个sql如下:
WITH tmp1 AS ( select xxx ),
tmp2 AS ( select xxxx ),
tmp3 AS ( select xxxx )
SELECT * FROM tmp1
我们需要提取到with临时表部分,然后将其跟 "SELECT * FROM tmp1" 分离开来,这时候方法如下:
public static void main(String[] args) {
// 正则表达式
String formatPattern = "(with[\\s\\S]+as?\\s*\\([\\s\\S]+\\))\\s*select";
// 待匹配字符串
String sql = "WITH tmp1 AS ( select xxx ), " +
"tmp2 AS ( select xxxx ), " +
"tmp3 AS ( select xxxx ) " +
"SELECT * FROM tmp1";
Pattern pattern = Pattern.compile(formatPattern);
Matcher matcher = pattern.matcher(sql.toLowerCase());
int selectLen = "select".length();
if (matcher.find()) {
String withFragment = matcher.group();
if (!StringUtils.isEmpty(withFragment)) {
if (withFragment.length() > selectLen) {
int lastSelectIndex = withFragment.length() - selectLen;
sql = sql.substring(lastSelectIndex);
withFragment = withFragment.substring(0, lastSelectIndex);
}
System.out.println("WITH部分:" + withFragment);
System.out.println("其他部分:" + sql);
}
}
}
输出为:
WITH部分:with tmp1 as ( select xxx ), tmp2 as ( select xxxx ), tmp3 as ( select xxxx )
其他部分:SELECT * FROM tmp1
以上,我们就可以很简单的把with部分 和 其他部分抽离出来了。
实际场景2 - PHP中将MySQL结果转为数组格式,格式如下:
将 var[^,]+ 替换为 => ''
其他语法描述
①分组
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
匹配:IP
2[0-4]\d|25[0-5]|[01]?\d\d?
含义:() 括住的 是分组后内容
②后向引用
\b(\w+)\b\s+\1\b
匹配:go go
\1
含义:每个 括号 括起来的叫一个分组,分组写法 \1 \2 \3
\b(?<Word>\w+)\b\s*\k<Word>\b #?<Word>\w+ 定义,\k<Word>捕获
③位置指定(匹配指定位置前后)
\b\w+(?=ing\b) # 零宽先行断言
匹配:I'm singing while you're dancing.
(?=ing\b)
(?<=\bre)\w+\b
reading a book
(?<=\bre)
④负向位置指定
\b\w*q(?!u)\w*\b
匹配:Iraq fighting
(?!u)
含义:匹配后缀( 非 u)
(?<![a-z])\d{7}
匹配:_1234567
(?<![a-z])
含义:匹配前缀( 非 a-z)
⑤贪婪和懒惰
*?
重复任意次,但尽可能少重复
+?
重复1次或更多次,但尽可能少重复
??
重复0次或1次,但尽可能少重复
{n,m}?
重复n到m次,但尽可能少重复
{n,}?
重复n次以上,但尽可能少重复
【转自:阜宁网页开发 http://www.1234xp.com/funing.html 欢迎留下您的宝贵建议】