月份彙整: 2017 年 9 月

Regular expression应用

最近在学习regular expression,刚巧项目上又有用到之处,故此把这两个我觉得挺有用的东西记录一下,以备后用:

1. 抽取SQL语句中Table的名字

一般SQL语句都是这个样子:

select *
from tables_a a
join tables_b b
on a.col = b.col

之前有个项目需要从上千个脚本之中抽取所有的Table名字出来,用人手做显然不可能,所以我最终决定使用regular expression。下面这两句一般来说已经足够:

(from)(\s)+([a-z_]+\.)*[0-9a-z_@]+
(join)(\s)+([a-z_]+\.)*[0-9a-z_@]+

第一句是将所有from后面的字符抽出来,第二句是将所有join后面的字符抽出来。MS SQL情况下,这种是没有问题的。但pl/sql的话,就有机会出现下面这种情况:

select *
from tables_a a, table_b b,
table_c c
where a.col = b.col
and b.col = c.col

遇上这种情况,只能用大包围方式,将所有有可能的字符也抽出来。

(,)(\s)*([a-z_]+\.)*[0-9a-z_@]+(\s)+[a-z0-9]+
([a-z_]+\.)*[0-9a-z_@]+(\s)+[a-z0-9]+(\s)*(,)

这大包围方式的坏处是会把column名字也抽出,到最后还是要人手看一次,不过也能省下不少时间。

2. 识别重复的pattern,并去重

识别重复pattern就是用上regular expression本身look ahead的功能。之前有个项目需要整理一些乱七八糟的数据,其中一项是从系统导出来的号码,不知为什么会自己重复,例如:

正常号码应该是:S1HK098723Y
导出来却变成:S1HK098723YS1HK098723Y

要识别这种变体不是很好弄,因为号码本身没有明确的分界符。但用regular expression一句就搞定

([a-zA-Z0-9]{5,})(\1)

之所以要限制第一组长度为5或以上,是因为要避免诸如00, XX等刚好有重复的字符。这个要因应情况修改。