查看原文
其他

本文作者:张 猛,中南财经政法大学金融学院本文编辑:王玉洁技术总编:戴 雯Stata&Python云端课程来啦!好消息!好消息!千呼万唤下,爬虫俱乐部Stata&Python数据分析线上沙龙活动将于11月17日下午3:00到5:00举办。本系列线上沙龙活动是为了促进各位学友关于Stata&Python数据分析学习的交流与探讨,分享在现阶段数据分析过程中遇到的困难、感悟,实现思维的碰撞,提升数据分析能力。有难题一起解决,有好东西一起分享,让学习不再孤独,让交流更加密切。此外我们推出了针对数据分析小白的课程优惠活动。活动详情及参与方式参见本期第二篇推文~今天小编为大家介绍的是Stata中正则表达式的贪婪模式。01贪婪模式的原理“贪婪”这个词是指不知满足,渴求更多,通过文字含义可以帮助我们更形象地理解贪婪模式,即在整个表达式匹配成功的前提下,尽可能多地匹配。所以在贪婪模式下,首先看整个字符串是否能与正则表达式匹配,如果匹配不成功,会去掉该字符串中的最后一个字符,并再次尝试匹配,如果匹配还是不成功,那么再去掉此时的最后一个字符。如果在去掉所有字符后仍然匹配不成功,那么会继续选取从第二个字符开始的整个字符串,重复上述的匹配过程。这个过程会一直重复,直到发现一个与正则表达式相匹配的字符串,或者全部尝试过后仍然匹配不出任何字符。对于贪婪模式,我们也可以简单理解为:首先吃掉所有的字符,然后一个一个吐出来,直到匹配成功。在Stata中,当使用除“{n}”之外的数量元字符时,会进入正则表达式匹配的贪婪模式。例如,利用正则表达式的贪婪模式,对字符串“abc”进行匹配。首先对整个字符串“abc”进行匹配;如果匹配不上,去掉最后一个字符“c”,对“ab”进行匹配;如果匹配不上,去掉最后一个字符“b”,对“a”进行匹配;如果匹配不上,将“abc”第一个字符“a”去掉,对“bc”进行匹配;如果匹配不上,去掉最后一个字符“c”,对“b”进行匹配;如果匹配不上,去掉“bc”中的第一个字符“b”,对“c”进行匹配。匹配成功一次或者对整个字符串遍历完成仍未匹配成功则运行结束。在介绍完贪婪模式的基本原理以后,小编还需要为大家介绍一项很重要的基本功——数量元字符,包括:"*"、"+"、"?"、"{m}"、"{m,n}"和"{m,}",在正则表达式的处理中懒惰模式需与数量元字符搭配使用。"*"表示匹配0到多次;"+"表示匹配1到多次(不能匹配0次);"?"表示匹配0次或1次;"{m}"表示匹配m次;"{m,n}"表示匹配m到n次;"{m,}"表示至少匹配m次;举一反三,我们也可以把前三种量词用另一种形式表达出来。"*"等价为"{0,};"+"等价为"{1,}";"?"等价为"{0,1}"。02实战演练下面我们用具体的例子来展示贪婪模式:clear set obs 5gen v = "A"+"B"*(_n - 1)为了方便观测,我们这里生成一组的变量v,由上到下分别为 "A" 、"AB"、 "ABB"、"ABBB"、"ABBBB"。gen v1 = ustrregexs(0) if ustrregexm(v,"AB*")gen v2 = ustrregexs(0) if ustrregexm(v,"AB{0,}")变量v1、v2匹配的是“A”加若干个(包含0个)“B”构成的字符串。由于v中的各个变量均符合所要求的格式,所以我们使用贪婪模式进行匹配时,在第一轮尝试时用整个字符串匹配时就能匹配成功。那么我们得到的v1、v2两组变量与变量v一致。gen v3 = ustrregexs(0) if ustrregexm(v,"AB+")gen v4 = ustrregexs(0) if ustrregexm(v,"AB{1,}")变量v3、v4匹配的是“A”与至少一个“B”构成的字符串。由于v中第一行变量没有“B”,匹配不到结果;v中其他变量均符合要求匹配的格式,在贪婪模式下第一轮对整个字符串的匹配中就成功匹配。故v3、v4第一行变量为空,后续变量与v相同。gen v5 = ustrregexs(0) if ustrregexm(v,"AB?")gen v6 = ustrregexs(0) if ustrregexm(v,"AB{0,1}")变量v5、v6匹配的是“A”与0或1个“B”构成的字符串,也即匹配”A“或”AB“。v中第一个变量为"A",匹配成功。后续的变量均为“AB...”格式,贪婪模式下,首先对整个字符串进行匹配,匹配失败后对字符串最后的字符依次删除,在删到只有“AB”时匹配成功。因此,除第一行外,v5、v6变量匹配的结果都是“AB”,因为轮不到去匹配“A”的机会。gen v7 = ustrregexs(0) if ustrregexm(v,"AB{3}")变量v7匹配的是“A”与三个“B”构成的字符串,即“ABBB”这一格式。对前三行变量进行匹配时,遍历完成仍未匹配成功。对“ABBB“(第四行)匹配时,首先对整个字符串进行匹配,即匹配成功。在对”ABBBB“(第五行)匹配时,首先对整个字符串进行匹配,匹配失败,然后删掉最后一个字符再进行匹配,随即匹配成功。所以前三行变量为空,最后两行变量为”ABBB“。gen v8 = ustrregexs(0) if ustrregexm(v,"AB{1,3}")变量v8匹配的是一个“A”与1-3个“B”构成的字符串,也即"AB"、"ABB"和"ABBB"。第一行变量匹配失败,二、三、四行变量在第一次对整个字符串进行匹配时就匹配成功。后续变量在第一轮遍历中依次删除最后的字符后也将在"ABBB"这个情况下匹配成功。gen v9 = ustrregexs(0) if ustrregexm(v,"AB{3,}")变量v9匹配的是一个“A”与至少3个“B”构成的字符串。前三行变量根本不存在三个“B”,遍历后匹配失败。后续变量在第一次对整个字符串进行试匹配时就匹配成功。故v9的前三行变量为空,后续变量与v一致。整体代码程序如下:clearset obs 10gen v = "A" + "B"*(_n - 1)gen v1 = ustrregexs(0) if ustrregexm(v,"AB*")gen v2 = ustrregexs(0) if ustrregexm(v,"AB{0,}")gen v3 = ustrregexs(0) if ustrregexm(v,"AB+")gen v4 = ustrregexs(0) if ustrregexm(v,"AB{1,}")gen v5 = ustrregexs(0) if ustrregexm(v,"AB?")gen v6 = ustrregexs(0) if ustrregexm(v,"AB{0,1}")gen v7 = ustrregexs(0) if ustrregexm(v,"AB{3}")gen v8 = ustrregexs(0) if ustrregexm(v,"AB{1,3}")gen v9 = ustrregexs(0) if ustrregexm(v,"AB{3,}")list, sep(0)整体程序运行结果如下图所示:根据上面的例子,我们可以看出来,贪婪模式下能匹配到长的字符串就轮不到短的字符串来匹配。但是我们要注意一点,贪婪模式并不是说我们匹配出的就是整个字符串中所能匹配到的最长的子字符串,我们应该根据贪婪模式的概念,从整个字符串开始试匹配,再从结尾处将一个一个字符剔除掉。也就是说在贪婪匹配模式下,匹配出的实际上是从尽可能靠近字符串开头的位置开始的,与正则表达式相匹配的最长的字符串。我们以下面的例子为例:clearset obs 1gen v = "123a456789"gen v1 = ustrregexs(0) if ustrregexm(v, "\d+")list可以发现,在贪婪模式下匹配的并不是整个字符串中最长的子字符串“456789”,而是以靠近字符串开头位置开始,与正则表达式相匹配的最长字符串“123”。它的匹配过程为:首先,元字符“\d”是一个特殊元字符,表示0-9任意一个数字,正则表达式“\d+”则表示至少1个的连续数字,匹配时,先匹配整个字符串“123a456789”,匹配不成功,然后去掉最后一个字符“9”,变为“123a45678”,仍然匹配不成功,再去掉最后一个字符“8”...,直到去掉字符“a”,变为“123”,即匹配成功。也就是说,由于字符”1“的位置靠前,让”123“的优先级高于”45678“,所以说贪婪模式下匹配最长的字符串是要以固定开头字符位置为前提的。今天关于正则表达式匹配模式之贪婪模式的介绍就到这里,有什么问题可以随时在后台咨询小编吖!最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。腾讯课堂课程二维码 对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!往期推文推荐 Seminar丨谁更重要:高管股权薪酬与财务报告欺诈 DOS能量,超乎你想象! 爬虫实战丨走进哈利波特的魔法世界 数据集合并的新路子-frlink命令 Seminar丨附近的公司:利用卫星图像研究本地信息优势 线性同余法生成伪随机数 [技能篇]多线程爬虫“好哭”是衡量一部好电影的标准吗?Stata&Python云端课程来啦!带你了解Stata中的矩阵Seminar|总统的朋友:政治关联与企业价值爬虫实战 | 爬取中国天气网爬虫实战 | 爬取东方财富网经济数据——以居民消费价格指数(CPI)为例Seminar|媒体关联董事对融资和外部治理的影响神奇的组内交叉合并 PDF分章节转TXT并实现可视化——以胡景北知青日记1971至1978年为例万物皆可开——shellout妙用无处不在的系列配置项|从零开始的Pyecharts(三)使用Python制作自动聊天机器人 fillin一下,平衡回来~order命令——快速改变变量顺序的利器 Ajax应用场景——以获取雪球网港股代码及公司名称为例播放列表中的歌单排行 在Stata中轻松运用program编写命令Meta Analysis in Stata17 芒果TV视频弹幕爬取之《我在他乡挺好的》Stata中的判断神器——confirm命令cngdf——名义GDP与实际GDP之间的摆渡船最近《扫黑风暴》有点火爆!我从豆瓣评论中发现了这些……随机森林-Random Forest 复原之神--preserve&restore合并,“纵”享新丝滑:frameappend & xframeappend什么是全局配置项?|从零开始的Pyecharts(二)关于我们 微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。 武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。投稿邮箱:statatraining@163.com投稿要求:1)必须原创,禁止抄袭;2)必须准确,详细,有例子,有截图;注意事项:1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。2)邮件请注明投稿,邮件名称为“投稿+推文名称”。3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存