作者:游万海 (福州大学) (知乎 | 简书 | 码云)
本期责任编辑:王俊
开始接受报名
image
给你一份公司年报,如何快速地从中找出与数值有关的内容。好朋友让你推荐好看的电影,如何快速地从豆瓣网站下载到每部电影的评分。 这里涉及到的问题就是如何从文本数据中挖掘出所需要的信息。Stata中的字符函数为这一操作的实现提供了便利,详细可以通过 查看具体的用法和实例。本文主要是针对字符函数里面的正则表达式函数 (regular expression)。
Stata14 之前的版本主要的正则表达式函数有:,和,reg代表regular,ex代表expression。匹配主要是基于 Henry Spencer's NFA 算法, 与 POSIX.2 标准相似。
:m代表match-----匹配。
:r代表replace-----替代。
:s代表subexpression-----截取。
Stata14 之前版本只能处理普通的ASCII字符,例如字母( a-z,A-z),数字 ( 0-9 )及普通的标点符号字符。Stata14 之后的版本加强了编码转换 (unicode),能够处理其他非普通编码ASCII字符,如中文,日语和韩语等。相应的,Stata14 引入了几个新的有关正则表达式命令:
Stata14 版本主要的正则表达式函数有:,, 和 ,unstr代表unicode string。
: 匹配
:f代表first。表示只替代第一次出现的匹配字符。
:a代表all。表示替代全部匹配到的字符。
: 截取
因此,Stata14 加强了正则表达式的功能,可以根据序列、POSIX 字符类等进行匹配。下面我们将进行一一说明。
一. 命令基本语法
本文以Stata14 之前版本的三个主要正则表达式命令为例,对其语法进行说明,如下图所示:
image
从上面语法可以看出,正确使用这些命令的一个关键点在于如何填写待匹配规则,比如想从文本中匹配出与数值有关的内容,可以用0-9,那么命令可以写为:
基于此,本文以下部分主要针对匹配内容的相关规定进行阐述,分别介绍元字符,序列,字符类,数量词,POSIX字符类等进行介绍。
二. 基本规则
(1)元字符
元字符是指的一类特殊字符,包括 等。匹配这些字符需要在前面加上。
例如:
若想匹配出包括 ,, 等特殊字符的部分,可以利用如下代码:
需要特别注意的是 符号比较特殊,其在 Stata 中还可以表示全局宏的引用,所以可以不加 。
(2) 序列
较为常用的序列主要有如下:
匹配数字字符
匹配非数字字符
匹配间隔符(空格)
匹配非间隔符(非空格)
匹配单词字符
匹配非单词字符
匹配词界
匹配非词界
第一: `\D` 表示非数值,`\d` 表示数值
回顾下前面的例子,若要从文本中匹配包括数值的部分,可以用0-9,这里也可以用 进行匹配。例如:
第二:`\w` 和 `\W` 表示单词和非单词字符。
单词字符是包括下划线的任何单词字符(字母,数字,下划线,汉字),即
第三:`\b` 和 `\B` 是位置匹配符
如果前面和后面的字符不全是 (字母,数字,下划线,汉字),则匹配;反过来理解就是,如果 的前面和后面都是 ,则不匹配。
前面讲的匹配都是匹配内容,而这里是匹配位置。这组命令也是非常常用,请看如下例子。
上述数据中都包括了ab字符,若我们只想匹配最后一个,看如下命令是否可以:
从匹配结果来看,把所有包括ab的元素都匹配出来的,这是因为遵循了贪婪匹配(greedy)模式。在这种情况下,我们可以使用位置匹配符进行限定。
哇,大家可以看到,index4 就是我们要的内容。这就是位置匹配符的神奇之处!此外,位置匹配符还包括^和$,匹配开始和结束位置。
例如:
(3) 字符类
字符类主要包括如下:
匹配任意元音字母
匹配任何一个大写元音
匹配任意单个数字
匹配任意数字(同上)
匹配任何ASCII小写字母
匹配任何ASCII大写字母
匹配任意上面的类
匹配除小写元音外的字母
匹配除数字外的字符
(4) 表示数量
表示数量有两类:
第一类:
前面待匹配的项目将匹配n个;
前面待匹配的项目将匹配n个或更多个;
前面待匹配的项目将匹配至少n个最多m个;
第二类:
前面的待匹配的项目是可选的,且最多匹配一个
前面待匹配的项目可以匹配0个或更多个
前面待匹配的项目将匹配一个或多个
(5) POSIX字符类
POSIX字符类是用 "[[ ]]“ 括起来的正则表达,常见的 POSIX 字符类有:
小写字母
大写字母
所有字母 ([[:lower:]] and [[:upper:]])
数字: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
字母和数字 ([[:alpha:]] and [[:digit:]])
空白字符: space and tab
控制字符
标点符号: ! ” # % & ' ( ) * + , - . / : ;
空格字符:制表符,换行符, 垂直制表符,换页符,回车和空格
十六进制数字: 0-9 A B C D E F a b c d e f
控制字符 ([[:alpha:]], [[:punct:]] and space)
图形化字符 ([[:alpha:]] and [[:punct:]])
(6) 回溯引用
我们先看这个例子(例子数据来源于 论坛):
若我们想取出I want this 1,I want this 2等,大家发现与前面说的匹配存在什么不同?前述例子我们都是从多个数中匹配出符合条件的数,而这里是从每个数中取出符合条件的一部分。这时候可以采用回溯引用方法。即先根据字符数据,利用正则表达式将完整的字符匹配出来,然后利用()来取出我们感兴趣的部分。这时可以利用 和 函数。
0表示匹配出来的全部内容;1表示第一个括号的内容;2表示第二个括号的内容;3表示第三个括号的内容。例如:
思考:
如何取出其中的数值部分?
(7) ()和[]的区别
(8) 常用匹配
(参考来源:https://blog.csdn.net/wangjia55/article/details/7877915)
匹配中文字符的正则表达式:
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:
评注:可以用来删除空白行
匹配 HTML 标记的正则表达式:
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)
匹配 Email 地址的正则表达式:
评注:表单验证时很实用
匹配网址 URL 的正则表达式:
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线):
评注:表单验证时很实用
匹配国内电话号码:
评注:匹配形式如 或
匹配腾讯 QQ 号:
评注:腾讯 QQ 号从 10000 开始
匹配中国邮政编码:
评注:中国邮政编码为 6 位数字
匹配身份证:
评注:中国的身份证为 15 位或 18 位
匹配 ip 地址:
评注:提取 ip 地址时有用
三. Stata 范例:利用正则表达式爬取豆瓣影评数据
说明:以下例子我主要是利用了外部命令 ,大家可以用上述讲过的命令试试
思考:上述程序只爬取了第一页的数据,若要爬取前10页的数据(^^这里仅做科研目的,大家悠着点,不要爬虫的太频繁),应该如何?
四、总结
若用Stata14以后的版本,尽量用ustr开头的命令,功能较为齐全。
学习正则表达式要多练习,多练习,多练习!!
参考资料
How can I extract a portion of a string variable using regular expressions?
What are regular expressions and how can I use them in Stata?
New program for regular expressions
Stata14 VS Stata13 之字符串函数 PK
Regular Expressions in Stata
Regular Expression Matching Can Be Simple And Fast
在线正则表达式测试
附录:推文 dofile 合集
【Stata: 正则表达式和文本分析】推文中的所有 dofile 文档
关于我们联系我们
领取专属 10元无门槛券
私享最新 技术干货