“ 正则表达式是文本处理中的利器,需要不断练习才能熟练掌握,在掌握了语法的基础上还需灵活运用,本文通过具体例子讲解如何在openrefine中运用正则表达式来提取信息。”
1.网页中的数据介绍
在网页中有F1分站赛的处罚信息,这些信息以条目的形式出现,我们的目的是:在openrefine中,将这些条目数据利用正则表达式提取出来,生成结构化表格,以便于后期的分析。
2.新建refine项目,选择剪切板的方式,将数据粘贴过来
3.去掉空白行
4.数据清洗
4.1生成包含比赛名称的列
if(value.contains('Prix'),value,"")
#根据Column1列新建一列 命名为race列
#contains(value,"Prix")返回的是TRUE or False,如果字符串中包含Prix字符,返回True,race列取值为value,否则取值为空字符串
#选race列,向下填充,将空格填充满
4.2 生成处罚通知的列
if(contains(value,'Prix'),'',value)
检查数据发现在56-59行出现了归类错误,主要原因是在处罚信息里包含了完整的比赛名称,由于量不是很大,可以直接用edit进行编辑。
编辑前:
编辑后:
4.3去除同一条数据跨多行的情况
检查发现,在penalty notice列中存在着一条数据分布在多行的情况,要将这种情况去除
image-20201023140111965.png
解决方法:
输入正则表达式:^[^-]
#含义是:匹配开头不是"-"的值,记住行号并用edit对单元格进行剪切-复制更改
penalty notice列,选择空白行,删除行
4.4 提取车手和车队名称
基于penalty notice列,新建列
使用Java正则语法:
value.match(/- (.*?)\s\(([\w ]+)\)?.*/).join('::')
注意:
1.'-'后面的空格
2.用'?'将贪婪模式改为非贪婪模式
3.\( \)转义为普通括号
4.()代表分组,返回括号内的值,本例中是两个字符串
5.match()匹配字符串,并返回括号中的值
# 使用python正则语法:
#import re
#return re.findall("- (.*)\s\((\w+)\)",value)
#import re
#text=re.search("- (.*)\s\((\w+)\)",value)
#return text.group(1)+'::'+text.group(2)
对车手车队列进行分面,检查提取的结果,发现有的行没有提取到信息,原因是没有 车手(车队)这种模式的字符串,手动更改单元格,删除Protest re Pirelli test行
4.5将车手车队列分成车手、车队两列(::分割)
4.6提取罚金
value.replace(',','').match(/.*€(\d+)/)[0]
#先将2,800中的','去掉再匹配正则
分面检查发现有的罚金没有提取出来(Java正则提取不出来,原因未知,后改用python正则),接下来再提取一次,选择罚金列中空的行,根据penalty notice 新建一列罚金2
value.replace('€',':').replace(',','')
选择罚金2,新建一列罚金1,使用python正则表达式
import re
return re.findall(".*:(\d+)",value)[0]
合并罚金列和罚金1列
4.7提取比赛阶段
比赛阶段主要有FP...或者Q...或者qualifying
value.match(/(?i).*((FP\d+)|(Q\d+)|(qualifying)).*/)[0]
#(?i)表示整体不区分大小写
4.8提取速度
value.match(/.*?(\d+\.?\d+)\skm\/h.*/)[0]