首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Stata:正则表达式和文本分析

作者:游万海 (福州大学) (知乎 | 简书 | 码云)

本期责任编辑:王俊

开始接受报名

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 1I 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 文档

关于我们联系我们

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190102G07QJ200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券