提取文本数据,分析师小王初上手!| 【SAS Says·扩展篇】正则表达式

文本分析很有用,数说君自己也玩过,炒鸡有意思,从论坛、网页上爬取网友的舆情数据,然后整理、统计、画图,就可以知道舆论的风暴是什么,可以知道网友最热议的话题、最想去的旅游景点、最喜欢的饮料等等,也可以从这些舆情数据中挖掘出两个话题之间的关联性等等。

扯的有点远,本系列【SAS Says · 扩展篇 · 正则表达式】介绍的是SAS里正则表达式的应用,对于一些杂乱无章的非结构化数据,正则表达式可是一个处理的利器!

它的使用其实很简单,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟甚至几秒钟完成!


【SAS Says·扩展篇】分析师小王初上手! | 1. PRXMATCH ()

本集目录:

0. 小王初上手

1. 初始PRXMATCH()

2. metacharater

2.1 什么是metacharater?

2.2 例子

2.3 metacharater总结

3. 问题解决

3.1 问题重述

3.2 问题理解

3.3 解决代码

数说工作室原创,转载只需放置数说工作室二维码,并注明来源。


0. 小王初上手

小王毕业了,才刚刚入职,公司为他做了张名片,名片上写着:

“小王 - 数说国际零售公司 - 数据分析部 - 初级数据分析师”

刚刚毕业的小王,是一位数据分析的新手,在公司里他负责为产品部提供所需的数据,并做分析和决策的辅助。

上班第一周,他就遇到了一个问题,这天,产品部的一个妹子找他来帮忙,问题是这样的:

数据库中有一份长长的产品名单,名单中有的是产品的名字,有的是产品的编号,产品部的妹子只想要产品的编号的那些行(下图红色字体的),以做更深一步的分析。

(01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12) 6753-5513 None here PD(12)6434-4532 P&DWashing ......(未显示完)

红色字体的编号似乎没有什么容易把握的规律:占位符不一样、也不全都是数字、有的行的括号后面还有空格等等,这怎么提取呢?

你是否在绞尽脑汁的想各种字符串函数、想各种匹配的规则,比如用substr(name,1,1) in (“(“,”P”),这个不行,因为有的非编号的行开头也可能是P、或者PD等......

可以歇歇了,因为小王只用了1分钟不到,就把代码写好并提取出来了,我们先来看下他的代码:

a=PRXMATCH("/\(\d\d\) ?\d{4}-\d{4}/", name); if a GT 0 then output;

结果为:

这代码是个什么玩意儿啊?

这些看起来像乱码的东西就是正则表达式和元字符,下面,我们就从一个函数PRXMATCH()来入手,学习一下如何使用正则表达式。

1. 初识PRXMATCH()

这个函数用来定义一段字符在一句话中的位置,它的格式为:

PRXMATCH ( pattern-id or regular-expression, string )

pattern-id大家先别管,这个函数的作用就是:看regular-expression 在 string 中的位置。

举个例子:

data _null_; STRING="I love Shushuo jun"; a=PRXMATCH("/Shu/",STRING); file print; put a=; run;

结果为:

Shu在I love Shushuo jun中的位置是8。

我们来解释一下 “/Shu/”

这是一个SAS的正则表达式例子,或者说,这是Perl正则表达式的例子,因为SAS里的正则表达就是按照Perl来的。

好吧,有点绕口,您请看下面这个图:

也就是说,这个双引号是SAS的语法,但里面的内容是标准的Perl正则表达式,看到那个斜杠 / 没有?那是默认的Perl分隔符。

如果您因此认为应该去找一本Perl的书去啃一啃,那就误会我的意思了,我只是告诉你这个事实而已,您只要关注数说工作室的连载就可以弄明白正则表达式。当然拿一本Perl的书学一学也是极好的。

好了,下面我们就要重点研究一下两腿之间....哦不,两个斜杠//之间的秘密,我们可以在两个斜杠之间放置一些元字符(metacharacter),来简化一些很复杂的表达。

2. metacharacter

2.1 什么是metacharacter?

metacharacter用来简化表达某种意思,比如在word中我们都知道\t代表的是制表符,那么在SAS正则表达式中也类似有:

^代表一段话的开头,

$代表一段话的结束,

\s代表的是一个空格(space)

……

他们就是metacharacter。

很抽象吧?所以我才要结合这个PRAXMATCH来介绍metacharater…

2.2 例子

来看一段代码:

data _null_; string1 = "I love Shushuo jun"; string2 = "Shushuo jun loves you"; a = PRXMATCH("/^Shu/",string1); b = PRXMATCH("/^Shu/",string2); file print; put a= b=; run;

运行结果如下:

所以简单来说,PRXMATCH(“/^Shu/”,string)匹配的是string的开头:开头是Shu,那么返回1,开头不是,则返回0。

string1开头不是Shu,故a返回0,string开头是Shu,故返回1。

我们学习了 ^ 这个metacharacter,它代表开头匹配,再学习几个:

  • $代表结尾匹配;
  • i代表不区分大小写;
  • \d 匹配任何某1个以上数位
  • \d\d\d 匹配任何某3个以上数位

先对这四个元字符举例:

data _null_; string1="I love Shushuo jun"; string2="Shushuo jun loves you"; a=PRXMATCH("/jun$/",string1); b=PRXMATCH("/jun$/",string2); c=PRXMATCH("/JUN/i",string1); d=PRXMATCH("/JUN/",string1); string3="12"; string4="12a"; string5="122"; string6="1222"; e=PRXMATCH("/\d\d\d/",string3); f=PRXMATCH("/\d\d\d/",string4); g=PRXMATCH("/\d\d\d/",string5); h=PRXMATCH("/\d\d\d/",string6); file print; put a= b= c= d= e= f= g= h=; run;

运行结果为:

解释:

1)注意$和i的使用位置:”/jun$/”和”/jun/i”,一个在斜杠里,一个在外。

2)a和b中,只有a返回了jun的位置,因为string1中,jun在末尾。

3)c和d中,只有c返回了,因为JUN是大写,必须用i符号,表示不区分大小写。

4)e、f返回的是0,因为\d\d\d要求必须至少要有3个数位。所以g、h返回的是1。

2.3 metacharater总结

我们给出一些metacharater总结,供以后使用的时候查询:

正则表达式

String

返回

不匹配(返回0)

/jun/

“Shushuo jun”

9

“Shushuo shuai”

/^jun/

“jun, I love you”

1

“I love you, jun”

/jun$/

“I love you, jun”

13

“jun, I Iove you”

/jun/i

“Shushuo jUn”

9

“Shushuo, xiong”

/\d\d\d /

“111”, “123”, ”328”…)

1

“1256”, “87”…

/\d\d\d?/

“123”, “42”…(2或3个数位)?可以让前面那一个字符可有可无

1

“1”, “1a1”, “4 9”…

/\d\d\d /

“123”, “345454”…(>=3个数位)+可以返回前面表达式+更多任何位

1

“1”, “12”…

/\d\d\d*/

“123”, ”12”, “3212”…(>=2个数位)*返回前面表达式少一位或更多任何位

1

“1”,”xyx”…

/\d{n}/

{n}表示匹配前面数位的n倍{n,}表示匹配前面数位n倍以上{n,m}表示匹配前面数位n倍以上,但不超过m倍

/s.u/

“shu”, ”s1u”, ”swwwwu”, ”s u”

1

“su”, “qu”…

/[1-5]\d[6-9]/

“269”,”537”…(首位是1-5、末尾是6-9的数)

1

“769”,”243”…

/(\d|x)\d/

“23”, “x6”…(\d|x表示数位或者字符串x)x|y表示匹配x或y

1

“2e”,”ty”…

/[^a-e]/

“r”, “t”…(除了a-e的任何字符串)

1

“c”,”e”…

/\D/

“ ”, “q”, “y”…(非数位符)

1

“1”, ”5”…

\)

“)” 返回左括号

\(

“(” 返回右括号

#//#

“//”

/\/\//

好了,我们现在要开始解释小王是怎么解决那个产品列表的问题的了。

3. 问题解决

3.1 问题重述

再重述一遍问题文中最开始的那个问题:

下面是某超市自己的产品列表,有的是编号,有的是产品的名字,我们现在用正则表达式,将产品编号的行(红色字体的)读取到SAS数据集中。

Name (01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12) 6753-5513 None here PD(12)6434-4532 P&DWashing ......(未显示完)

3.2 问题理解

首先我们意义理解一下,我们只要有产品编号的行,产品编号的格式为:

(XX)XXXX-XXXX

但也包括下面的情况:

1)有的编号前面有字母PD,它标志出过期的产品。

2)有的编号()后面还有一个空格,比如(12) 6753-5513。

综上所述,正则表达式应该这样“编码”:

编号

P

D

(

XX

)

空格

XXXX

-

XXXX

正则表达式

P?

D?

\(

\d\d

\)

空格?

\d{4}

-

\d{4}

空格?表示这个空格有或没有,都被匹配,P?和D?也是同样道理。因此,提取出编号的正则表达式就应该为:

“/P?D?\(\d\d\) ?\d{4}-\d{4}/”

3.3 解决代码:

综上解释,我们给出小王的代码:

data production; input name $char20.; a=PRXMATCH("/\(\d\d\) ?\d{4}-\d{4}/",name); if a GT 0 then output; datalines; (01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12) 6753-5513 None here PD(12)6434-4532 P&DWashing ; proc print noobs; title 'Production ID'; var name; run;

运行结果为:

这里为方便解释,产品名单我们就用显示出来的那几个,你可能会说:

产品名单里也许还有其他没考虑到的情况呢?你的正则表达式一定可靠吗?

肯定有没考虑到的情况,所以才有下一集啊。

本文分享自微信公众号 - 数说工作室(shushuojun)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-12-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算D1net

国内自主云计算服务器已具备国际竞争力

2月11日上午10点,发展改革委高技术司副巡视员孙伟作客中国政府网,解读国务院办公厅日前印发的《关于促进云计算创新发展培育信息产业新业态的意见》。 孙伟表示,我...

424110
来自专栏原创

如何打造100亿SDK累计覆盖量的大数据系统

作为推送行业领导者,截止目前个推SDK累计安装覆盖量达100亿(含海外),接入应用超过43万,独立终端覆盖超过10亿 (含海外)。个推系统每天会产生大量的日志和...

40590
来自专栏新智元

【与AlphaGo的同与不同】阿里巴巴双11上任AI调度官达灵,数据中心资源利用率提升至90%以上

作者:胡祥杰 【新智元导读】双十一来临前,阿里发布了数据中心AI调度官“达灵”,达灵”通过应用强化学习、组合优化等技术,可以在复杂环境中自行学习判断,作出一系列...

44080
来自专栏云计算D1net

我们从云计算中领悟到的10件事

云计算在十年之前就已经能够出现在我们的生活中,虽然在今天它已经拓展到多个维度,但是追根溯源,我们所说的云计算是伴随着1999年Saleforce.com的上线以...

37450
来自专栏杨建荣的学习笔记

数据访问层的优化思路(r10笔记第80天)

对于数据访问层的优化,我简单总结了一下,其实里面有很多的点子现在想起来有一种灵光一现的感觉,但是真真切切的,里面有不少是之前公司已经做到了的,所以一个做产品的公...

32970
来自专栏ml

HDUOJ----1181 变形课

变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java...

34460
来自专栏ml

HDUOJ-----(1329)Calling Extraterrestrial Intelligence Again

Calling Extraterrestrial Intelligence Again Time Limit: 2000/1000 MS (Java/Other...

36860
来自专栏新智元

【华为邵洋】华为终端人工智能战略:端侧智能+云端智能,2019开启下一个时代

【新智元导读】新智元AI WORLD2017 世界人工智能大会上,华为消费者业务首席战略官邵洋带来 《Mobile AI,重新定义极致用户体验》的分享。他提到,...

520100
来自专栏量子位

Google发布tf.Transform,让数据预处理更简单

为了方便用户为机器学习进行数据预处理,Google今天发布了tf.Transform。 以下内容来自Google Research Blog,量子位编译 每当要...

47290
来自专栏原创

个推 Spark实践教你绕过开发那些“坑”

Spark作为一个开源数据处理框架,它在数据计算过程中把中间数据直接缓存到内存里,能大大地提高处理速度,特别是复杂的迭代计算。Spark主要包括SparkSQL...

443100

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励