用正则表达式揭开回车键的面纱

Posted 爬虫俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用正则表达式揭开回车键的面纱相关的知识,希望对你有一定的参考价值。

在下载pdf版上市公司年报之后,我们再将pdf转换为txt文本文档,最后将文本文档导入到stata进行词频统计,这时会遇到一个问题,年报的某些词被分在不同的行中。我们以广州白云国际机场股份有限公司(600004)公司年报为例:

用正则表达式揭开回车键的面纱

以上截取了公司年报的一部分,可以看到“合并”一词被分在两行中,导入stata后是什么样呢?

infix strL v 1-20000 using e:/600004.txt, clear

drop if v == ""

用正则表达式揭开回车键的面纱

这时候,我们进行词频统计时,由于“合并”被分到了两行当中,这个词将不会被匹配到。怎么解决这个问题呢,在推文“”我们介绍了可以用fileread()函数可以将只有一行的且不以换行符结尾的文本文档导入stata,同时用fileread()函数读入文本文档的话,会将所有内容读入同一个单元格内。那么,我们是否可以利用fileread()函数把文本文档读入一个单元格内进行统计呢?我们进行尝试(并统计出来这时候合并的个数,以便与下边结果进行对比):

clear

set more off

set obs 1

gen v = fileread("600004.txt")

moss v, match("合并")

用正则表达式揭开回车键的面纱

这里我们统计出来“合并”的个数为161,但是被分行的“合并”事实上还是没有被统计到,原因是我们可以看到stata上方编辑框中“广州白云国际机场股份有限公司”、“600004”、“2016年年度报告”等这些在文本文档中处于不同行的字符串导入到stata中后被类似于“空格”的字符分隔开,因此在不同行的“合并”也会被这些类似于“空格”的字符分隔开,从而不会被统计到。很直观的办法,我们只需要把这些类似“空格”的字符删除掉,问题就得到了解决。那么首先我们要弄清楚,这些字符究竟是什么?


用正则表达式揭开回车键的面纱

我们还延续上篇推文中的例子,先用file命令生成一个命名为“文档”的txt文件,这个txt文档一共有两行,第一行为“爬虫俱乐部”;第二行为“将爬虫进行到底”,且文档末尾不以换行符结尾。然后我们再用fileread函数导入stata:

tempname temp

file open `temp' using 文档.txt, text write replace

file write `temp' "爬虫俱乐部" _n

file write `temp' "将爬虫进行到底"

file close `temp'

clear

set more off

set obs 1

gen v = fileread("文档.txt")

用正则表达式揭开回车键的面纱

用正则表达式揭开回车键的面纱

注意了!我们点击v[1]这个观测值,在stata的上方的编辑框中却只显示“爬虫俱乐部”!好是奇怪,我们接着看一下,这个观测值的unicode字符长度:

gen len = ustrlen(v)

用正则表达式揭开回车键的面纱

字符串“爬虫俱乐部将爬虫进行到底”unicode字符长度本应是12,结果却是14,很显然有两个字符是我们观察不到的。

用正则表达式揭开回车键的面纱

在stata中,控制字符(例如:换行符(LF)、换页符(FF)、回车符(CR)等)是显示不出来的。

那么这两个字符究竟是什么呢?之所以在stata上方编辑器中只显示出来“爬虫俱乐部”是因为其换行了。这里我们首先要介绍一下两个正则表达式元字符:

用正则表达式揭开回车键的面纱

\r表示回车符,\n表示换行符,\r\n匹配一个“回车+换行”组合。有许多操作系统(比如windows)都把\r\n用作文本行的结束标签。Unix和Linux系统只使用一个换行符(\n)来结束一个文本行;Mac系统上只使用一个回车符(\r)来结束一个文本行。

\r表示回车符,英文是Carriage return,其使光标到行首;\n表示换行符,英文是New line,其使光标下移一格,我们平常用windows系统敲一个回车键,其实质上即是回车,又是换行(\r\n),即(Enter = 回车+换行(\r\n))。

这时候,我们再考虑上述问题,由于文档.txt中“爬虫俱乐部”和“将爬虫进行到底”两行之间有一个回车键,即回车+换行(\r\n),用fileread函数导入到stata中,虽然显示不出来,但事实上是存在的。所以在stata编辑框中只显示了“爬虫俱乐部”,而下一行“将爬虫进行到底”没有显示出来。接下来,为了方便大家观察到这两个控制字符,我们用正则表达式将其替换为其他字符:

replace v = ustrregexra(v,"\r","❤")

replace v = ustrregexra(v,"\n","○")

用正则表达式揭开回车键的面纱

我们可以看到,回车符被字符“❤”替换了,换行符被字符“○”替换了,并且由于不存在回车键(回车+换行(\r\n)),stata编辑框中显示了整个字符。

当然,我们也可以把这两个字符替换为missing:

replace v = ustrregexra(v,"\r\n","")

用正则表达式揭开回车键的面纱

另外,需要注意的是,当变量的字符长度超过2045时,观测值就会变为灰色的字符串,我们导入一个字符长度超过2045的文本,并且文本内有多行,例如:

用正则表达式揭开回车键的面纱

clear

set more off

set obs 1

gen v = fileread("文档.txt")

用正则表达式揭开回车键的面纱

为了显是的更清楚,我们list一下:

list

用正则表达式揭开回车键的面纱

   我们发现文档.txt中句子换行的地方,导入stata后都有类似于“空格”的字符串,其实它们就是回车+换行(\r\n)这两个控制字符。同样我们可以把它们替换为missing:

replace v = ustrregexra(v,"\r\n","")

list

用正则表达式揭开回车键的面纱

再回到文章开头的问题,事实上,开头提到的类似“类似”空格的字符就是回车+换行(\r\n)这两个控制字符。因此我们可以将其删除掉,再进行词频统计:

replace v = ustrregexra(v,"\r\n","")

moss v, match("合并")

用正则表达式揭开回车键的面纱

这里统计出来的“合并”一词为162个,而文章开头统计的个数为161,说明被分在两行的“合并”被统计到了。这时候我们又发现一个问题,在stata编辑框中“2017年4月28日”与“2016年年度报告公司代码:600004”之间依然有一些空白字符,为了方便观察,下边给出对应的文本文档:

用正则表达式揭开回车键的面纱

这些空白字符事实上就是所在行的空格,我们利用正则表达式“\r\n”只是把导致换行的“空白字符”(回车和换行符)删除掉了,并没有把空格进行删除。

用正则表达式揭开回车键的面纱

制表符、回车符、换行符等导入到stata中,表示的就是1个或多个连续的空格。

但是这里我们并没有利用正则表达式“\s”把所有的空格都删除掉,原因是有些制表符或空格是不能删除的,例如表格中两个单元格之间的空格如果我们删除了,那么单元格之间的内容就连在了一起,因此我们只需要把导致换行的字符(回车和换行符)删除掉,使不同行之间的内容连接在一起就行。

实力技术贴啊,小编忍不住要给这篇推文的作者点赞,啥也不说了,我去打赏了!


以上就是今天给大家分享的内容了,说得好就赏个铜板呗!有钱的捧个钱场,有人的捧个人场~。

                     文字编辑:高娜娜

技术总编:刘贝贝



往期推文推荐:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.




关于我们

此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

欢迎关注爬虫俱乐部


以上是关于用正则表达式揭开回车键的面纱的主要内容,如果未能解决你的问题,请参考以下文章

7.4 Javascript:表单验证-揭开正则表达式的面纱

Js高级---你所不知道的正则表达式的神秘!

新手上路:图文解读助你理解和使用正则表达式

ORACLE 用正则表达式匹配 回车换行

大佬们 用js正则验证多个IP用回车分隔该怎么写?

awk 正则 去掉回车换行