一、需求缘起
最近遇到一个老同学问我能不能帮他,将下面表格里的车牌号、金额、日期提取出来,大概4000多条数据。他自己人工找的话,很麻烦,尤其是每隔几天就得搞一次。我说你把数据脱敏下,给我一些测试数据,我有空帮他看看。
| 序号 | 数据举列 |
|---|---|
| 1 | 我方长租车京AAB1234,驾驶员李四,于2022/8/15发生单方事故,我司车辆全责。我方车辆经过保险公司定损,定损金额2400元,申请该车理赔资料盖章,后续赔款由保险公司直接赔付车辆所在的修理厂账户。 |
| 2 | 我方网约车鲁AD78765,于2022年03月24日与对方车辆发生交通事故,我方车辆负全责任,对方车辆无责任。我方车辆经保险公司定损,定损金额为15943.5元,申请该车理赔资料盖章,后续赔款由保险公司直接赔付车辆所在的修理厂账户。 |
| 3 | 我方网约车闽AD04567于12月6日发生交通事故,我司车辆无责。我方车辆经保险公司定损,定损金额为3000元,申请该车理赔资料盖章,后续赔款由保险公司直接赔付车辆所在的修理厂账户。 |
| 4 | 我司车辆苏ED98765于2022年4月7号发生交通事故,我方车辆负事故无责任,对方车辆苏URJ568负事故全部责任,我方车辆在合作4S店定损维修,定损金额10200元,维保单号TT2022062900071,现申请授权理赔打款至某4S店 |
| ... | *** 此处省略4000多条,以上数据已脱敏 |
一眼望去,一下就想到用正则,经过分析,但是发现确实定制化挺高,一些常用的正则根本解决不了问题。
二、提取目标分析
1、车牌号好提取,但车型不同,位数又不同,一条数据会出现多个车牌号
2、年月日好提取,但又格式不统一,2022/8/15,2022年03月24日,12月6日,2022年4月7号等
3、金额好提取,但是包含小数、单位不统一
三、经过多次尝试后”定稿“正则表达式如下:
1、车牌正则:/[测京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}[A-Z]{1}[A-Z0-9]{1,5}[A-Z0-9挂学警港澳]{1}/g
2、日期正则:/(20[0-2]{2}[年/])?[0-9]{1,2}[月/][0-9]{1,2}[号日]*/g
3、金额正则:/[\w.]+元/g
也许有更好的写法,欢迎大家拍砖指导。
四、复盘回顾 - 温故知新
1、定义字符集合
可以使用元字符[和]来定义一个字符集合。在使用[和]定义的字符集合里,这两个元字符之间的所有字符都是该集合的组成部分,字符集合的匹配结果是能够与该集合里的任意一个成员相匹配的文本。
如车牌号的第一个字:[测京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]
又如:2022/8/15 和 2022年03月24日的分割符:[年/]、[月/],这里注意 / 这斜杠,放在字符集里的时候可以不用\ 反斜杠转义。
如果是连续也可以简写如:日期正则中的[0-2],表示年份的第三位和第四位,取值范围都是0-2,[0-2]相当于[012]。
2、匹配的重复次数
可以用{n}为重复匹配次数设定一个精确的值,n是个整数。
如:日期正则的{2}意味着模式里的前一个字符(或字符集合)必须在原始文本里连续重复出现2次才算是一个匹配;如果只重复了1次,则不算是一个匹配。
又如:[测京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}的{1}, 限制出现一次就行了。
3、为重复匹配次数设定一个区间
{}语法还可以用来为重复匹配次数设定一个区间——也就是为重复匹配次数设定一个最小值和一个最大值。这种区间必须以{1,5}这样的形式给出——{1,5}的含义是最少重复1次、最多重复5次。
如:车牌号正则里的{1,5},这就可以解决位数不同的问题。
4、有多少个匹配
\w可以匹配所有的字母和数字字符以及下划线字符_
如:金额正则里就用了\w。但是要记得,\w不能匹配出现在字符串中间的.字符。
要想干净彻底地解决金额的特点这个问题,需要匹配\w或.。用正则表达式的术语来说,我们需要匹配字符集合[\w.]。
5、匹配一个或多个字符集合
+可以用来匹配一个或多个字符集合。
如:金额正则中的+,因为你不知道数据中是多大金额。最后加上”元“进行边界控制即可。
6、只能匹配零个或一个字符
?只能匹配零个或一个字符
如日期正则中(20[0-2]{2}[年/])?里的问号,加了它,即使数据里没有年份,像4月3日,也能正常提取出来。
7、使用子表达式
子表达式是一个更大的表达式的一部分;把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式必须用(和)括起来。
如:日期正则中(20[0-2]{2}[年/]),这里用到子表达式,因为数据里的日期有可能没有年份,用子表达式将整个年份括起来,结合后面的?会起到,匹配的时候你年份有没有我都起作用。
8、慎用“贪婪型”元字符
*和+都是所谓的“贪婪型”元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止的。
五、测试举例 - JavaScript
正则表达式语言并不是一种完备的程序设计语言,它甚至算不上是一种能够直接安装并运行的程序。更准确地说,正则表达式语言是内置于其他语言或软件产品里的“迷你”语言。这里用 JavaScript举例。
六、其他知识点可以参考
2)《正则表达式必知必会》这本书不错的,勤翻多看。因为它不算高级语言,忘记了就在回顾一遍。总会用熟练的。