tidyverse —— stringr包

本文介绍了R语言中用于字符串处理的stringr包,详细解析了如何使用该包进行字符串连接、截取、正则表达式匹配等操作,并通过实例展示了str_c、str_sub、str_detect、str_count等函数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

640?wx_fmt=gif

作者简介

野菜团子,R语言中文社区专栏作者 

博客:https://ask.hellobi.com/blog/esperanca 


stringr包,顾名思义,处理字符串专用包,本篇笔记对它进行简单介绍。提到字符串处理,有一个绕不过去的主题,它是字符串处理的利器,也是字符串处理的问题制造机,它就是——正则表达式。本篇笔记顺带介绍一下正则表达在R语言中的应用。

1.  连接字符串

在base包中,字符串的连接主要用paste和paste0两个函数,在stringr包中,它们的替代品是str_c()函数。举个简单的例子:

str_c("x", "y","z")
str_c("x", "y", sep =", ")

640?wx_fmt=png


str_c()继承R语言函数的矢量化运算风格,会对参数进行循环计算,直到更长的那个参数的完结:

str_c("", c("a","b", "c"), "-suffix")

640?wx_fmt=png


2.  截取子集

要截取字符串中的一段,使用str_sub()函数。str_sub()函数接受两个数字参数作为截取字段起止的位置。不同于Python等其他语言的索引从0开始,R语言从1开始计数,并且包含截止的位置。举个例子:

x <- c("Apple","Banana", "Pear")

str_sub(x, 1, 3)
str_sub(x, -3, -1)

640?wx_fmt=png


负数表示从字符串的右边开始进行截取。


3.  正则表达式

好了,开始我最喜欢也最头疼的正则表达部分。先说通配符“.”,它能够匹配除了新行外的所有字符,那么如果想要匹配它本身,就需要对它进行转义。在其他诸如stata中,我们在之前加上反斜杠“\”表示转义,但是,在R语言中,我们使用字符串的形式来表示匹配模式,而在字符串中“\”本身是有特殊用法的字符,需要对它进行转义来表示转义,就需要加两个反斜杠。比如下面这个例子,我们用str_view函数来显示匹配结果:

str_view(c("abc", "a.c","bef"), "a\\.c")

640?wx_fmt=png


如上图,双反斜线转义后才能匹配字符串中的“.”。

那么对于反斜线“\”本身呢?我们要怎么匹配它?

大家可能会觉得,转义要两个反斜杠,再加上本身一个,要三个反斜杠。

640?wx_fmt=png


真这么简单我何必特意问出来。

答案是要4个。

大家在R语言中设置当前路径的时候,如果在路径中使用了反斜杠,就需要写两个“\”,前一个表示转义,因为反斜杠本身在字符串中有特殊的含义,所以转义是必须的。同理,在R语言中,文本中要表示“\”,需要两个反斜杠“\\”来表示。而要构建一个正则模式来匹配文本中的这两个反斜杠“\\”,首先是这两个反斜杠得有,就是两个,再注意一下,匹配模式本身也是文本,在文本中要表达一个反斜杠,就要在之前多加一个,所以在原有的两个反斜杠前各加一个反斜杠,就一共有四个。就像这样:

x <- "a\\b"
str_view(x, "\\\\")

640?wx_fmt=png

好啦,除了这一点需要特别点出来,R语言中的正则就和其他Perl啊、Python啊啥的语言一样,大致没什么特别的了。接下来介绍相关的函数。


4.  探测匹配

4.1 str_detect函数

str_detect函数用来探测是否在字符串中匹配到给定的模式,返回布尔值来表示结果。用words这个数据集,我们来匹配一下以“ac”开头的单词:

head(words)
head(str_detect(words, "^ac"))

640?wx_fmt=png


“^”表示只匹配行开头的部分,与之相对的是“$”,表示只匹配行的结尾部分。

计算一下words中以元音字母结尾的单词的比例:

mean(str_detect(words, "[aeiou]$"))

640?wx_fmt=png


中括号“[]”表示匹配其中的任意元素,“[^]”则表示匹配除了中括号里的元素外的所有元素。比如上代码还可以表示为1减去以辅音字母结尾的单词比例:

1 - mean(str_detect(words, "[^aeiou]$"))

640?wx_fmt=png


4.2 str_count函数

str_count函数用来计数给定的模式被匹配上了多少次。比如计算words中每个单词中有多少个元音字母:

head(words)
head(str_count(words, "[aeiou]")) 

640?wx_fmt=png


5.  提取匹配

5.1 str_extract函数

有时候我们不仅想要知道匹配了多少次,还想知道具体匹配到了什么,这时候就可以用str_extract函数。以sentences数据为例,我们想要知道含有颜色的句子有哪些,都含有哪些颜色:

color_match <- str_c("red","orange", "yellow", "green", "blue","purple", sep = "|")
has_color <- str_subset(sentences,color_match)
matches <- str_extract(has_color,color_match)
head(matches)

640?wx_fmt=png


str_extract函数只提取第一个匹配值,如果要匹配所有,就用str_extract_all函数。

more <- sentences[str_count(sentences,color_match) > 1]
str_extract_all(more, color_match)

640?wx_fmt=png


返回的结果是一个列表,可以用tidyr包的unnest函数修整成tibble格式的数据,也可以设置simplify = TRUE来返回一个矩阵:str_extract_all(more, color_match, simplify= TRUE)

640?wx_fmt=png


5.2 str_match函数

str_match函数在需要提取多个匹配值时非常趁手。比如想要匹配sentences中的名词,我们假定名词前都有冠词the/a/an中的一个,其后跟一个空格,再跟一个非空格的元素组,那么我们给出如下的匹配模式:

noun <- "(the|a|an) ([^ ]+)"

()表示匹配模式组别,“+”表示前一个匹配值出现超过一次。我们需要提取的有两个匹配值,一个是第一个括号里的冠词,一个是第二个括号里的名词。

has_noun <- sentences %>% str_subset(noun)%>% head(10)
has_noun %>% str_extract(noun)
has_noun %>% str_match(noun)

640?wx_fmt=png


对比str_extract函数把两个匹配值提取成一个字符串,str_match把我们要的冠词和名词分别列出。str_match也只匹配第一个,如果要提取所有的名词和冠词,可以用str_match_all函数。


6.  替换匹配

str_replace函数替换匹配到的第一个模式,str_replace_all则可以替换所有。比如:

x <- c("1 house", "2 cars", "3 people")
str_replace_all(x, c("1" = "one", "2" ="two", "3" = "three"))

640?wx_fmt=png


7.  拆分

str_split函数将字符串向量进行拆分,以sentences数据为例,按空格进行拆分:

sentences %>% head(5) %>% str_split("", simplify = T)

640?wx_fmt=png


同样可以进行字符串拆分并且可以使用正则表达式的还有之前讲到的tidyr包的separate函数。


8.  其他模式

在R语言中,使用一个字符串格式的模式时,是自动调用正则表达式的。如果想要匹配的内容不需要调用正则就能解决,就可以使用fixed函数,来避免烦人的转义,而且也更省时。比如,如果要匹配文本中的反斜杠,配合fixed函数只用两个反斜杠就行了:

a <- 'hello\\wor\\ld'
writeLines(a)
str_extract_all(a, fixed('\\'))

640?wx_fmt=png

而如果要匹配的内容非常繁琐,则可以选择设置comments = TRUE,这样可以在正则模式中添加注释,比如Hadley的例子:

phone <- regex("
\\(? # optional opening parens
(\\d{3}) # area code
[)- ]? # optional closingparens, dash, or space
(\\d{3}) # another threenumbers
[ -]? # optional space or dash
(\\d{3}) # three more numbers
", comments = TRUE)
str_match("514-791-8141",phone)


一个小tip,fixed和regex函数都有ignore _case选项,设置为TRUE后可以无视大小写进行匹配。


最后,附上stringr包的cheatsheet下载地址,想要了解更多的盆友们可以看看:

https://github.com/rstudio/cheatsheets/raw/master/strings.pdf



往期回顾

tidyverse —— dplyr包

tidyverse —— readr包

tidyverse —— readxl包


640?wx_fmt=jpeg

公众号后台回复关键字即可学习

回复 爬虫            爬虫三大案例实战  
回复 
Python       1小时破冰入门

回复 数据挖掘     R语言入门及数据挖掘
回复 
人工智能     三个月入门人工智能
回复 数据分析师  数据分析师成长之路 
回复 机器学习      机器学习的商业应用
回复 数据科学      数据科学实战
回复 常用算法      常用数据挖掘算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值