强大的正则表达式
本文作者:李婷婷,河南大学经济学院
本文编辑:王 彤
技术总编:余术玲
爬虫俱乐部云端课程
导读
正则表达式(regular expression)是一种强大、便捷、高效的文本处理的工具,其通常被用来匹配、提取、替换那些符合某个模式(规则)的文本。网络爬虫时,提取目标信息是很关键的一步。这时正则表达式就发挥了很大的作用,可以很方便的帮助我们从复杂的源代码中提取目标信息,今天就简单的介绍一下正则表达式匹配、提取和替换函数的用法。
正则表达式匹配函数
匹配:ustrregexm(s,re[,noc])
其中u代表unicode;str代表string,即字符串;regex代表regular expression,即正则表达式;m代表match,即匹配。若正则表达式re能与字符串s中的某个子字符串匹配,则返回值为1,否则为0。在默认情况下,匹配是区分大小写的,但是如果定义noc为一个不为零的数,则匹配时不区分大小写。
接下来通过简单易懂的小例子来看一下正则表达式匹配函数的用法。
dis ustrregexm("Stata", "S") //在Stata中匹配到了S,因此返回值为1
dis ustrregexm("Stata","s") //在Stata中没有匹配到s,因此返回值为0
dis ustrregexm("Stata","s",0) //在区分大小写的情况下,在Stata中没有匹配到s,因此返回值为0
dis ustrregexm("Stata","s",1) //在不区分大小写的情况下,在Stata中匹配到了s,因此返回值为1
上边的几行程序及输出结果直观的向大家展示了正则表达式匹配函数的用法,以及是否区分大小写的不同情况。
正则表达式提取函数
提取:ustrregexs(n)
其中u、str和regex与匹配函数中所表示的含义相同;s代表substring,即子字符串。提取出的字符串为ustrregexm(s, re [,noc])
函数中第n个子表达式对应的子字符串。若n=0,则提取出整个正则表达式对应的子字符串。ustrregexs(n)
函数必须与ustrregexm(s, re [,noc])
函数一起使用。
首先生成一个观测值为“StataPython”,接下来分别看看使用正则表达式匹配和提取函数进行匹配、提取文本的不同情况。
clear
set obs 1
gen str v = "StataPython"
list
gen v1=ustrregexs(0) if ustrregexm(v,"StataPython") //0表示提取引号内所有表达式对应的字符串
gen v2=ustrregexs(1) if ustrregexm(v,"(Stata)(Python)") //1代表第1个括号内的子表达式对应的子字符串
gen v3=ustrregexs(2) if ustrregexm(v,"(Stata)(Python)") //2代表第2个括号内的子表达式对应的子字符串
gen v4=ustrregexs(0) if ustrregexm(v,"(Stata)(Python)") //v4和v1提取结果相同,说明子表达式的添加不影响匹配结果
list
*嵌套子表达式
gen v5=ustrregexs(1) if ustrregexm(v,"((Stata)(Python))") //嵌套子表达式中第1个子表达式为第1个左边小括号对应的子表达式
gen v6=ustrregexs(2) if ustrregexm(v,"((Stata)(Python))") //嵌套子表达式中第2个子表达式为第2个左边小括号对应的子表达式
gen v7=ustrregexs(3) if ustrregexm(v,"((Stata)(Python))") //嵌套子表达式中第3个子表达式为第3个左边小括号对应的子表达式
list
通过上边的小例子可以很容易理解正则表达式匹配和提取函数的基本用法。
正则表达式替换函数
替换:ustrregexrf(s1,re,s2[,noc])
和ustrregexra(s1,re,s2[,noc])
其中u、str和regex与匹配函数中所表示的含义相同;r代表replace,即替换;f代表first,a代表all。两个函数分别代表将正则表达式re在字符串s1中匹配到的所有子字符串中的第一个或全部替换为字符串s2。在默认情况下,匹配是区分大小写的,但是如果定义noc为一个不为零的数,则匹配时不区分大小写。
接下来举例说明正则表达式替换函数的基本用法:
dis ustrregexrf("GOOD&good","good","X") //将good替换为了X
dis ustrregexrf("GOOD&good","Good","X") //没有匹配到Good,因此没有发生替换
dis ustrregexrf("GOOD&good","Good","X",0) //在区分大小写的情况下,没有匹配到Good,因此没有发生替换
dis ustrregexrf("GOOD&good","Good","X",1) //在不区分大小写的情况下,Good既可以匹配GOOD,也可以匹配good,f表示将匹配到的第一个子字符串替换掉,即替换了GOOD
dis ustrregexra("GOOD&good","Good","X",1) //在不区分大小写的情况下,Good既可以匹配GOOD,也可以匹配good,a表示将匹配到的所有子字符串替换掉,即替换为了X&X
从上边的例子及其得出的结果中,可以直观的了解到正则表达式替换函数ustrregexrf
和ustrregexra
的基本用法以及区分大小写的不同情况。
实战举例
在之前的推文(《我和我的家乡》影评高频词原来是这些!)中也使用了正则表达式,不知道大家是否还记得呢?接下来就以提取网页第一页中所有影评标题和链接为例来看一下正则表达式在其中的用法。
在网页的源代码中,可以观察到标题和链接都位于含有</a></h2>
的行,因此我们需要的就是利用正则表达式保留目标行、提取影评的标题和链接,以便之后使用链接进一步抓取影评内容。
我们将网页的源代码读入Stata中。
clear all
cap mkdir D:/影评爬取
cd D:/影评爬取
copy "https://movie.douban.com/subject/35051512/reviews" temp.txt, replace
infix strL v 1-100000 using temp.txt, clear
先使用正则表达式匹配函数匹配到包含有</a></h2>
的行并保留下来。
keep if ustrregexm(v,"</a></h2>")
接下来使用正则表达式匹配和提取函数提取影评链接,我们发现链接位于<a href="
和">
之间,因此用`"<a href="(.*)">"'
来匹配链接,程序如下:
gen url=ustrregexs(1) if ustrregexm(v,`"<a href="(.*)">"')
最后再通过正则表达式替换函数得到影评的标题。通过观察发现,影评标题的特征是位于尖括号之外,因此我们只需要删除掉尖括号内的信息,而保留尖括号外的信息就可以了,使用正则表达式替换函数和<.*?>
匹配到所有尖括号和尖括号里的内容并删除掉,就得到了影评的标题。程序如下:
replace v =ustrregexra(v,"<.*?>","")
rename v title //将变量v重命名为title
如上图所示,就得到了第一页所有影评的标题和链接。
关于正则表达式还有很多内容值得学习,如果大家在学习的过程中遇到什么问题,欢迎在评论区留言交流哦!
自动群发邮件(二)——附带附件
自动群发邮件--email和smtplib基本模块的使用
计算工作日的小能手——workdays
Seminar | 企业错报与银行贷款合同
小贴士:Markdown的基本语法
听说相貌也能量化 | 调用百度人脸检测API实现颜值打分
列出指定属性的变量|findname命令比ds命令
Json文件好帮手——JsonPath
pyecharts绘图——河流图展示
你知道MDPI期刊的热门题目吗?
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。