用函数
gsub
base包中的 gsub() 可以替换/删除字符串中的各种标点符号/字母/数据

删除字符串a中的双引号

gsub(’["]’, ‘’, string_a)

在gsub函数中,任何字段处理都由将“替换字符”替换到“目标字符”这一流程中实现,令替换字符为’’’'可实现删除,令替换字符为"目标字符+增补内容"可实现增补,替换和切割也是使用类似的操作。

text <- “AbcdEfgh . Ijkl MNM”
gsub(“Efg”, “AAA”, text) #将Efg改为AAA,区分大小写
[1] “AbcdAAAh . Ijkl MNM”

任何符号,包括空格、Tab和换行都是可以识别的

gsub(" I", “i”, text) #可识别空格
[1] “AbcdEfgh .ijkl MNM”

同时字符可以识别多个,进行批量置换

gsub(“M”, “N”, text)
[1] “AbcdEfgh . Ijkl NNN”

除此之外,gsub还有其他批量操作的方法

gsub("^.* “, “a”, text) #开头直到最后一个空格结束替换成a
[1] “aMNM”
gsub(”^.* I(j).*KaTeX parse error: Expected 'EOF', got '#' at position 17: …, "\\1", text) #̲只保留一个j [1] "j" …", “b”, text) #第一个空格直达结尾替换成b
[1] “AbcdEfghb”
gsub("\.", “\+”, text) #句号.和加号+是特殊的,要添加\来识别
[1] “AbcdEfgh + Ijkl MNM”

Syntax Description
\d Digit, 0,1,2 … 9
\D Not Digit
\s Space
\S Not Space
\w Word
\W Not Word
\t Tab
\n New line
^ Beginning of the string
$ End of the string
\ Escape special characters, e.g. \ is “”, + is “+”
| Alternation match. e.g. /(e|d)n/ matches “en” and “dn”
• Any character, except \n or line terminator
[ab] a or b
[^ab] Any character except a and b
[0-9] All Digit
[A-Z] All uppercase A to Z letters
[a-z] All lowercase a to z letters
[A-z] All Uppercase and lowercase a to z letters
i+ i at least one time
i* i zero or more times
i? i zero or 1 time
i{n} i occurs n times in sequence
i{n1,n2} i occurs n1 - n2 times in sequence
i{n1,n2}? non greedy match, see above example
i{n,} i occures >= n times
[:alnum:] Alphanumeric characters: [:alpha:] and [:digit:]
[:alpha:] Alphabetic characters: [:lower:] and [:upper:]
[:blank:] Blank characters: e.g. space, tab
[:cntrl:] Control characters
[:digit:] Digits: 0 1 2 3 4 5 6 7 8 9
[:graph:] Graphical characters: [:alnum:] and [:punct:]
[:lower:] Lower-case letters in the current locale
[:print:] Printable characters: [:alnum:], [:punct:] and space
[:punct:] Punctuation character: ! " # $ % & ’ ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
[:space:] Space characters: tab, newline, vertical tab, form feed, carriage return, space
[:upper:] Upper-case letters in the current locale
[:xdigit:] Hexadecimal digits: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
————————————————
版权声明:本文为CSDN博主「lztttao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lztttao/article/details/82086346

删除字符串a中的下划线_

gsub(’[_]’, ‘’, string_a)

把字符串a中的数字1换成中文一

gsub(’[1]’, ‘一’, string_a)

把字符串a中的字母a换成字母A

gsub(’[a]’, ‘A’, string_a)

1
2
3
4
5
6
7
8
9
10
11
12
substring
这个函数可以提取字符串的一部分

substring()函数的基本语法是:

substring(x,first,last)

以下是所使用的参数的说明:
x - 是字符向量输入。
first - 是第一个字符要被提取的位置。
last - 是最后一个字符要被提取的位置。

result <- substring(“Extract”, 5, 7)
print(result)
[1] “act”
————————————————
版权声明:本文为CSDN博主「Yann_YU」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Yann_YU/article/details/107232946

  1. 准备工作
    stringr 不是tidyverse 核心 R 包的一部分,故需要使用命令来加载它。

library(tidyverse)
library(stringr)
2. 字符串基础
2.1 创建字符串或字符向量

(1)用单引号或双引号来创建字符串。

单引号和双引号在 R中没有区别。一般用双引号。单引号通常用于分隔包含"的字符向量。

string1 <- “This is a string” #用"创建字符串
string2 <- ‘To put a “quote” inside a string, use single quotes’ #字符串中含"时,用"来创建字符串
如果要在字符串中包含一个’或",需要用 \ 对其进行“转义”(也就是说,\在字符串中有特殊含义,即“转义”):

writeLines("’") # writelines() 函数用于查看字符串的初始内容

writeLines(’"’)
"
如果要在字符串中包含一个反斜杠,需要用两个反斜杠:\。

writeLines(’\’)

其他特殊字符列表(用 ?’"’ 或 ?"’" 命令来查看)

Image

writeLines("\u00b5")
μ
(2)用 c() 函数来创建字符向量(包含多个字符串)

c(“one”, “two”, “three”)
[1] “one” “two” “three”
2.2 字符串长度:str_length() 函数

功能:返回字符串中的字符数量:

用法:str_length(string)

str_length(c(“a”, “R for data science”, NA))
[1] 1 18 NA
2.3 字符串组合:str_c() 函数

(1)str_c() 函数-stringr包中的函数

功能:将多个字符串连接成一个字符串。

用法:str_c(…, sep = “”, collapse = NULL)

参数 … :字符串列表或字符向量

参数 sep :分隔符,默认不分隔

参数 collapse :将字符向量中的字符串合并,并用提供的分隔符分隔

str_c(“x”, “y”, “z”) # 输入为3个字符串"x", “y”, “z”
[1] “xyz”

str_c(“x”, “y”, “z”, sep = ", ") # 用“逗号+空格”分隔
[1] “x, y, z”

str_c(c(“x”, “y”, “z”), collapse = ", ") # 输入为1个字符向量c(“x”, “y”, “z”)
[1] “x, y, z”
长度为 0 的对象会被丢弃,这与 if 结合起来特别有用

name <- “Hadley”
time_of_day <- “morning”
birthday <- TRUE
str_c(
"Good ", time_of_day, " “, name,
if (birthday) " and HAPPY BIRTHDAY”,
“.”
)
[1] “Good morning Hadley and HAPPY BIRTHDAY.”

birthday <- FALSE
str_c(

  • "Good ", time_of_day, " ", name,
  • if (birthday) " and HAPPY BIRTHDAY",
  • “.”
  • )
    [1] “Good morning Hadley.”

str_c() 函数是向量化的,它可以自动循环短向量,使得其与最长的向 量具有相同的长度:

str_c(“prefix-”, c(“a”, “b”, “c”), “-suffix”) # "prefix-"和 "-suffix"是短向量,c(“a”, “b”, “c”)是长向量
[1] “prefix-a-suffix” “prefix-b-suffix” “prefix-c-suffix”
缺失值是可传染的。如果想要将它们输出为 “NA”,可以使用 str_ replace_na():

x <- c(“abc”, NA) # 1个字符向量,包含2个字符串
str_c("|-", x, “-|”) # 组合字符串,没有特殊说明时,缺失值可传染
[1] “|-abc-|” NA
str_c("|-", str_replace_na(x), “-|”) # 用 str_replace_na()将缺失值输出为 “NA”,
[1] “|-abc-|” “|-NA-|”
(2) paste() 和 paste0() 函数-R语言内置函数

功能:连接字符串

用法:

paste (…, sep = " ", collapse = NULL, recycle0 = FALSE) #可自定义分隔符,默认为空格

paste0(…, collapse = NULL, recycle0 = FALSE) #字符串间紧密连接

x <- “apple”
y <- “banana”
paste(x,y)
[1] “apple banana”
paste0(x,y)
[1] “applebanana”
处理NA时与str_c()的区别:str_c()中NA有传染性,paste()将NA返回成字符

x <- “apple”
z <- NA
paste(x,z)
[1] “apple NA”
str_c(x,z)
[1] NA
2.4 字符串取子集:str_sub() 函数

功能:提取或修改字符串的一部分。

用法:str_sub(string, start = 1L, end = -1L)

参数start和end:Start给出第一个字符的位置(默认为第一个),end给出最后一个字符的位置(默认为最后一个字符)。

x <- c(“Apple”, “Banana”, “Pear”)
str_sub(x, 1, 3)
[1] “App” “Ban” “Pea”
即使字符串过短, str_sub() 函数也不会出错,它将返回尽可能多的字符:

str_sub(“a”, 1, 5)
[1] “a”
用 str_sub()替换字符串:通过 函数的赋值形式来实现

str_sub(x, 1, 1) <- str_to_lower(str_sub(x, 1, 1)) # str_to_lower()将文本转化为小写
x
[1] “apple” “banana” “pear”
2.5 区域设置

(1)str_to_upper(),str_to_title()

功能:将文本转化为大写

用法:str_to_upper(string, locale = “en”)

参数locale:区域设置,默认为“en”(英语)。区域设置可以参考 ISO 639 语言编码标准,语言编码是 2 或 3 个字母的缩写,见下表,如“tr”(土耳其语)

str_to_upper(c(“i”, “ı”), locale = “tr”) # 土耳其语中有带点和不带点的两个i,它们在转换为大写时是不同的:
[1] “İ” “I”
str_to_upper(c(“i”, “ı”)) #默认区域设置是英语,转化成大写时是一样的
[1] “I” “I”
(2) str_sort() 和 str_order() 函数

功能:排序

参数locale:区域设置

x <- c(“apple”, “eggplant”, “banana”)
str_sort(x, locale = “en”) # 英语
[1] “apple” “banana” “eggplant”
str_sort(x, locale = “haw”) # 夏威夷语
[1] “apple” “eggplant” “banana”

用英语和夏威夷与排序时的结果是不一样的

  1. 用正则表达式进行模式匹配:str_view() 函数
    正则表达式(Regular Expression)

是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。描述了一种字符串匹配的模式(pattern)。通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。

str_view() 和 str_view_all() 函数

用法:

str_view(string, pattern, match = NA) 显示第一个匹配

str_view_all(string, pattern, match = NA) 显示所有匹配

参数match:为TRUE时只显示匹配项,为FALSE时只显示不匹配项,为NA时显示匹配项和不匹配项(默认)

要显示str_view()匹配的结果,还需要额外安装两个 R 包:htmltools 和 htmlwidgets。

很多 stringr 函数都是成对出现的:一 个函数用于单个匹配,另一个函数用于全部匹配,后者会有后缀 _all。

htmltools包可以用 library() 直接安装

library(htmltools)

htmlwidgets包直接安装不,可以试着用下面命令安装

BiocManager::install(“htmlwidgets”)
library(htmlwidgets)
str_view()匹配的结果显示在右下角窗格中

Image

3.1 基础匹配

(1) 精确匹配字符串

x <- c(“apple”, “banana”, “pear”)
str_view(x, “an”)
Image

(2)用.可以匹配任意字符(除了换行符)(但只能匹配1个字符):

str_view(x, “.a.”)
Image

(3)如何匹配字符 . 呢?

. 可以匹配任意字符,正则表达式用\来去除某些字符的特殊含义,因此,要匹配.,需要的正则表达式是.(前面加1个\来去除.匹配任意字符的特殊含义,使其仅用来匹配.)。

\ 在字符串中也用作转义字符(去除某些字符的特殊含义),因此,正则表达式 . 的字符串形式应是 \.

str_view(c(“abc”, “a.c”, “bef”), “a\.c”)
Image

(4)如何匹配\呢?

要匹配\,需要的正则表达式是\,对应的字符串形式为"\\"

x <- “a\b”
writeLines(x)
a\b
str_view(x, “\\”)
Image

3.2 锚点

默认情况下,正则表达式会匹配字符串的任意部分。

需要从字符串的开头或末尾进行匹配时,要设置锚点。

^ 从字符串开头进行匹配。

$ 从字符串末尾进行匹配。

x <- c(“apple”, “banana”, “pear”)
str_view(x, “^a”) # 匹配字符串开头的a
str_view(x, “a$”) # 匹配字符串末尾的a

x <- c(“apple pie”, “apple”, “apple cake”)
str_view(x, “apple”) #正则表达式默认匹配字符串的任意部分,只要含apple即可,这里3个字符串中的apple都会匹配到
str_view(x, “^apple$”) #严格匹配到第2个字符串,不仅含apple,且字符串以a开头以e结尾
\b 匹配单词间的边界

x <- c(“The green light in the brown box flickered.”,“Glue the sheet to the dark blue background.”,“Hedge apples may stain your hands green.” )

匹配x中的颜色

colors <- c(“red”, “orange”, “yellow”, “green”, “blue”, “purple”) # 创建颜色名称向量
color_match <- str_c(colors, collapse = “|”) # 将颜色名称向量转化为正则表达式
str_view_all(x,color_match) # 匹配x中的颜色

发现第一个句子中的flickered也被匹配到了,该怎么修改?

color_match2 <- str_c("\b(",color_match,")\b") # 在pattern前后加\b(单词边界)
str_view_all(x,color_match2)
3.3 字符类与字符选项

很多特殊模式可以匹配多个字符。(虽然可以匹配多个,但是一次只匹配一个,想匹配多次见3.4)

.可以匹配除换行符外的任意字符。

\d 可以匹配任意数字。

\s 可以匹配任意空白字符(如空格、制表符和换行符)

[abc] 可以匹配 a、 b 或 c。

[^abc] 可以匹配除 a、 b、 c 外的任意字符。

注意:要想创建包含 \d 或 \s 的正则表达式,需要在字符串中对 \ 进行转义,因此需 要输入 “\d” 或 “\s”。

| 的优先级很低(最后才考虑|),所以 abc|xyz 匹配的是 abc 或 xyz,而不是 abcyz 或 abxyz。

如果优先级让人感到困惑,那么可以使用括号让其表达得更清晰一些:如gr(e|a)y匹配的是grey或gray。

3.4 重复

正则表达式的另一项强大功能是,其可以控制一个模式能够匹配多少次。(是将它前面的字符匹配多少次)

?:0 次或 1 次。相当于{0,1}

+:1 次或多次。相当于{1,}

*:0 次或多次。相当于{0,}

x <- “1888 is the longest year in Roman numerals: MDCCCLXXXVIII”
str_view(x, “CC?”) #"CC?"是将第2个C匹配0次或1次,也就是说匹配的是C或CC。
str_view(x, “CC+”) #"CC+"是将第2个C匹配1次或多次,也就是说匹配的是连续2个以上的C
str_view(x, ‘C[LX]+’) #'C[LX]+'是将[LX]匹配1次或多次,[LX]意思是匹配L或X,也就是说只要C后面接的是L或X都可以匹配到,直到不是L或X为止。
注意:这些运算符的优先级非常高(也就是说优先考虑匹配次数),因此很多时候需要使用括号

x <- c(“color”,“colour”,“banana”,“bananana”)
str_view(x, “banana+”, match = TRUE) #"banana+"是将最后一个a匹配1次或多次,匹配的是banana或bananaaaa…,这里只能匹配到第3个和第4个字符串中的banana
str_view(x, “bana(na)+”, match = TRUE) #"bana(na)+"是将最后的na匹配1次或多次,比如banana或bananana,这里第3个和第4个字符串可以全部匹配到
还可以精确设置匹配的次数

{n}:匹配 n 次。

{n,}:匹配 n 次或更多次。

{,m}:最多匹配 m 次。

{n, m}:匹配 n 到 m 次。

x <- “1888 is the longest year in Roman numerals: MDCCCLXXXVIII”
str_view(x, “C{2}”) #"C{2}"是将C匹配2次,即匹配的是CC
str_view(x, “C{2,}”) #"C{2,}"是将C匹配2次以上,也就是说可以匹配连续2个以上的C
str_view(x, “C{2,3}”) #"C{2,3}"是将C匹配2~3次,也就是说匹配的是CC或CCC
正则表达式默认会匹配尽量长的字符串(默认的匹配方式是“贪婪的”,如果有长的就匹配长的,没长的就匹配略短的)。

在正则表达式后面加一个 ?,可以将匹配方式更改为“懒惰的”,即匹配尽量短的字符串。

str_view(x, “C{2,3}”) #"C{2,3}"匹配方式为贪婪,如果字符串含CCC,那匹配的是CCC而非CC。当然,如果只有2个连续C那匹配的就是CC,如果有4个连续C那匹配的还是前3个C。
str_view(x, “C{2,3}?”) #"C{2,3}?"匹配方式为懒惰,即匹配的是CC。
str_view(x, ‘C[LX]+?’) #'C[LX]+?'匹配方式为懒惰,即匹配的是CL或CX。
练习

用语言描述以下正则表达式匹配的是何种模式(仔细阅读来确认我们使用的是正则表达式,还是定义正则表达式的字符串)?
a. ^.*$ #这是正则表达式,.*表示重复0次以上的.,这里^和$表示以任意字符开始,以任意字符结束,故这个匹配的是任意字符。
b. “\{.+\}” #这是定义正则表达式的字符串,由于{和}在正则表达式中有特殊含义,所以\{匹配的是单纯的{,\}匹配的是},.+表示重复1次以上的.,.在正则表达式中可匹配任意字符,故这个匹配的是任意花括号里有至少1个字符的字符串,如"{a}“或”{abc}"等
c. \d{4}-\d{2}-\d{2} #这是正则表达式,\d可以匹配任意数字,{4}意思是将任意数字匹配4次,故这个匹配的是4位数字后接一个连字符,然后是两个数字后接一个连字符,然后是另外两个数字。这是一个正则表达式,可以匹配格式为“YYYY-MM-DD”(“%Y-%m-%d”)的日期。如2021-08-16
d. “\\{4}” #这是定义正则表达式的字符串,正则表达式的字符串中\\匹配的是\,故这个匹配的是\\。

找出以 3 个辅音字母开头的单词
str_view(words,"[aeiou]{3}",match=TRUE) #这里[^aeiou]可以匹配任意非元音字母(辅音字母),但只能匹配一个字母,{3}是匹配3次辅音字母

找出有连续 3 个或更多元音字母的单词。
str_view(words,"[aeiou]{3}",match=TRUE)

找出有连续 2 个或更多元音—辅音配对的单词
str_view(words,"([aeiou][^aeiou]){2,}",match=TRUE)
3.5 分组与回溯引用

括号的作用:

阐明优先级,用于消除复杂表达式中的歧义。【前部分】

能对正则表达式进行分组,分组可以在匹配时回溯引用(如 \1、 \2 等)【本部分】

提取一个复杂匹配的各个 部分【后部分】

回溯引用

回溯引用可以匹配到捕获组曾经匹配过的结果。

回溯引用的标志是反斜杠后加数字

回溯引用中的数字是从左至右计算的。回溯引用中的\1对应第一个圆括号中的内容,\2对应第二个圆括号中的内容。

找出名称中有重复的一对字母的所有水果

str_view(fruit, “(…)\1”, match = TRUE) #"(…)\1"中…表示匹配任意两个字符,\1表示回溯引用第一个()中的内容,由于用字符串表示,所以表示为\1,故这个匹配的是名称中有重复的一对字母的所有水果
练习

用语言描述以下正则表达式会匹配何种模式?
(.)\1\1 #同一字符重复3次,如"aaa"
“(.)(.)\2\1” #一对字符镜像出现,如"abba"
(…)\1 #任意2个字符重复,如"a1a1"
“(.).\1.\1” #注意这是定义正则表达式的字符串,表示“一个字符后面跟着任意字符,原始字符,任何其他字符,再重复原始字符”,如"abaca"或"b8b.b",即一共5个字符,第1、3、5个字符一样,其余随意。
“(.)(.)(.).*\3\2\1” 表示“三个字符,后面跟着0个或多个任

字符,后面跟着三个相同的字符,只是顺序相反”,如“abcsgasgddsadgsdgcba”或“abccba”或“abc1cba”。
4. 工具
基本思想:将一个复杂问题分解为多个简单问题

4.1 匹配检测:str_detect() 函数

(1)str_detect() 函数

功能:确定一个字符向量能否匹配一种模式,判断的是能否匹配,故结果是逻辑向量,即TRUE或FALSE

用法:str_detect(string, pattern, negate = FALSE),negate为TRUE 则返回不匹配的元素

判断x的3个字符串中是否含e

x <- c(“apple”, “banana”, “pear”)
str_detect(x, “e”)
[1] TRUE FALSE TRUE
str_detect(x, “e”, negate = TRUE)
[1] FALSE TRUE FALSE
从数学意义上来说,逻辑向量中的 FALSE 为 0, TRUE 为 1。这使得在匹配特别大的向量时,sum() 和 mean() 函数能够发挥更大的作用:

以t开头的常用单词有多少个?

sum(str_detect(words, “^t”)) # words中共有980个单词,其中以t开头的有65个,也就是说str_detect(words, “^t”)的结果中有65个TRUE(数学意义上=1),915个FALSE(数学意义上=0),65个1与915个0的和为65。
[1] 65

sum(…, na.rm = FALSE)函数中的…可以是数字,也可以是逻辑向量

以元音字母结尾的常用单词的比例是多少?

mean(str_detect(words, “[aeiou]$”)) # words中共有980个单词,其中以元音字母结尾的有271个,也就是说str_detect(words, “^t”)的结果中有271个TRUE(数学意义上=1),709个FALSE(数学意义上=0),271个1与709个0的均值为0.2765306。
[1] 0.2765306
str_detect() 函数的一种常见用法是选取出匹配某种模式的元素。

通过逻辑取子集方式,来选取出匹配某种模式的元素

[是取子集函数,调用方式为x[i],逻辑向量取子集方式可提取出TRUE值对应的所有元素(见课本15.4.5向量取子集)

words[str_detect(words, “xKaTeX parse error: Expected 'EOF', got '#' at position 6: ")] #̲提取出 words 中str_…”)结果为TRUE(以x结尾)的元素
[1] “box” “sex” “six” “tax”

或用str_subset() 包装器函数,来来选取出匹配某种模式的元素

str_subset(words, “x$”)
[1] “box” “sex” “six” “tax”
如果正则表达式过于复杂,则应该将其分解为几个更小的子表达式,将每个子表达式的匹配结果赋给一个变量,并使用逻辑运算组合起来。

找出以 x 开头或结尾的所有单词

用str_subset()函数选取匹配某种模式的元素

str_subset(words,"^x|x$") # words中没有以x开头的单词,以x结尾的单词有4个
[1] “box” “sex” “six” “tax”

通过逻辑取子集方式选取匹配某种模式的元素

words[str_detect(words,"^x|x$")] #选出 words 中结果为TRUE的元素
[1] “box” “sex” “six” “tax”

将其分解为2个简单问题,将结果赋值给变量,然后使用逻辑运算组合起来

start_with_x <- str_detect(words,"^x")
end_with_x <- str_detect(words,“x$”)
words[start_with_x|end_with_x]
[1] “box” “sex” “six” “tax”

字符串通常会是数据框的一列,此时我们可以使用 filter 操作

df <- tibble(word = words, i = seq_along(word)) #seq_along()用于生成序列,df是一个数据框(2个向量,一个word,一个序号)
df %>% filter(str_detect(words, “x$”)) #筛选出df中word以x结尾的行

A tibble: 4 x 2

word i

1 box 108
2 sex 747
3 six 772
4 tax 841
(2)str_count()函数

功能:返回字符串中匹配的数量

用法:str_count(string, pattern = “”)

x <- c(“apple”, “banana”, “pear”)
str_count(x, “a”) # 返回字符串中a的个数
[1] 1 3 1
mean(str_count(words, “[aeiou]”)) # str_count(words, “[aeiou]”)返回words中每个单词中含元音字母的个数,求均值即为“平均来看,每个单词中含元音字母的个数”
[1] 1.991837

哪个单词包含最多数量的元音字母?

vowels <- str_count(words, “[aeiou]”)
words[which(vowels == max(vowels))]
[1] “appropriate” “associate” “available” “colleague” “encourage” “experience”
[7] “individual” “television”

哪个单词包含最大比例的元音字母? (提示:分母应该是什么?)

prop_vowels <- str_count(words, “[aeiou]”) / str_length(words)
words[which(prop_vowels == max(prop_vowels))]
[1] “a”

str_count() 也完全可以同 mutate() 函数一同使用

df %>% mutate(vowels = str_count(word, “[aeiou]”), consonants = str_count(word, “[^aeiou]”)) #在df基础上添加2列vowels和consonants,表示每个单词中含元音字母和辅音字母的个数

A tibble: 980 x 4

word i vowels consonants

1 a 1 1 0
2 able 2 2 2
3 about 3 3 2
4 absolute 4 4 4
5 accept 5 2 4
6 account 6 3 4
7 achieve 7 4 3
8 across 8 2 4
9 act 9 1 2
10 active 10 3 3

… with 970 more rows

注意:匹配从来不会重叠。

str_count(“abababa”, “aba”) # "abababa"中,模式 “aba” 会匹配2次,而不是3次
[1] 2
4.2 提取匹配内容:str_extract() 函数

功能:提取匹配的实际文本

找出包含一种颜色的所有句子

colors <- c(“red”, “orange”, “yellow”, “green”, “blue”, “purple”) #创建一个颜色名称向量
color_match <- str_c(colors, collapse = “|”) #将颜色名称向量转换成一个正则表达式
has_color <- str_subset(sentences, color_match) #选取出包含一种颜色的句子
matches <- str_extract(has_color, color_match) #从选取出的句子中提取出颜色
head(matches) #显示前6个匹配结果
[1] “blue” “blue” “red” “red” “red” “blue”
str_extract(string, pattern) 只提取第一个匹配

str_extract_all(string, pattern, simplify = FALSE) 可以提取全部匹配。

逻辑向量取子集方式一般与比较函数结合起来使用效果更佳,提取出TRUE值对应的所有元素(见课本15.4.5向量取子集)

(more <- sentences[str_count(sentences, color_match) > 1])
[1] “It is hard to erase blue or red ink.”
[2] “The green light in the brown box flickered.”
[3] “The sky in the west is tinged with orange red.”

str_extract() 只提取第一个匹配

str_extract(more, color_match)
[1] “blue” “green” “orange”

str_extract() 可以提取全部匹配,并返回为一个列表

str_extract_all(more, color_match)
[[1]]
[1] “blue” “red”

[[2]]
[1] “green” “red”

[[3]]
[1] “orange” “red”

str_extract_all()的参数 simplify 默认为FALSE,返回字符向量列表;如果为TRUE,则返回一个字符矩阵,其中较短的匹配会扩展到与最长的匹配具有同样的长度:

simplify = TRUE,返回一个矩阵

str_extract_all(more, color_match, simplify = TRUE)
[,1] [,2]
[1,] “blue” “red”
[2,] “green” “red”
[3,] “orange” “red”

较短的匹配会扩展到与最长的匹配具有同样的长度

x <- c(“a”, “a b”, “a b c”)
str_extract_all(x, “[a-z]”, simplify = TRUE)
[,1] [,2] [,3]
[1,] “a” “” “”
[2,] “a” “b” “”
[3,] “a” “b” “c”
练习

从 Harvard sentences 数据集中提取以下内容。
a. 每个句子的第一个单词。
pattern <- “[A-Za-z][A-Za-z’]*”
b. 以 ing 结尾的所有单词。
pattern <- “\b[A-Za-z]+ing\b”
c. 所有复数形式的单词。
pattern <- “\b[A-Za-z]{3,}s\b”
4.3 分组匹配:str_match() 函数

功能:可以给出每个独立分组。

用法:

str_match(string, pattern)

str_match_all(string, pattern)

结果:str_match() 返回的不是字符向量,而是一个矩阵,其中一列是完整匹配,后面的列是每个分组的匹配:

用括号来提取一个复杂匹配的各个部分

noun <- “(a|the) ([^ ]+)”
has_noun <- sentences %>% str_subset(noun) %>% head(10)

str_extract()函数可以给出完整匹配,返回的是字符向量

has_noun %>% str_extract(noun)
[1] “the smooth” “the sheet” “the depth” “a chicken” “the parked” “the sun” “the huge”
[8] “the ball” “the woman” “a helps”

str_match()函数则可以给出每个独立分组,返回的是一个矩阵,其中一列是完整匹配,后面的列是每个分组的匹配:

has_noun %>% str_match(noun)
[,1] [,2] [,3]
[1,] “the smooth” “the” “smooth”
[2,] “the sheet” “the” “sheet”
[3,] “the depth” “the” “depth”
[4,] “a chicken” “a” “chicken”
[5,] “the parked” “the” “parked”
[6,] “the sun” “the” “sun”
[7,] “the huge” “the” “huge”
[8,] “the ball” “the” “ball”
[9,] “the woman” “the” “woman”
[10,] “a helps” “a” “helps”

如果数据是保存在 tibble 中的,那么使用 tidyr::extract() 会更容易。这个函数的工作方式 与 str_match() 函数类似,只是要求为每个分组提供一个名称,以作为新列放在 tibble 中:

tidyr::extract()的第一个参数是数据框,第2个参数是列名,第3个参数是正则表达式,remove = TRUE表示从输出数据帧中移除输入列。

tibble(sentence = sentences) %>% tidyr::extract(sentence, c(“article”, “noun”), “(a|the) ([^ ]+)”, remove = FALSE )

A tibble: 720 x 3

sentence article noun

1 The birch canoe slid on the smooth planks. the smooth
2 Glue the sheet to the dark blue background. the sheet
3 It’s easy to tell the depth of a well. the depth
4 These days a chicken leg is a rare dish. a chicken
5 Rice is often served in round bowls. NA NA
6 The juice of lemons makes fine punch. NA NA

… with 714 more rows

4.4 替换匹配内容:str_replace() 函数

功能:用新字符串替换匹配内容

用法:str_replace(string, pattern, replacement) replacement表示替换的字符向量,即把pattern匹配到的内容替换为replacement

用法1:用固定字符串替换匹配内容(replacement为固定字符串)

x <- c(“apple”, “pear”, “banana”)
str_replace(x, “[aeiou]”, “-”) #将x中的第1个元音字母替换为-
[1] “-pple” “p-ar” “b-nana”
str_replace_all(x, “[aeiou]”, “-”) #将x中的所有元音字母替换为-
[1] “-ppl-” “p–r” “b-n-n-”
用法2:通过提供一个命名向量,使用 str_replace_all() 函数可以同时执行多个替换

x <- c(“1 house”, “2 cars”, “3 people”)
str_replace_all(x, c(“1” = “one”, “2” = “two”, “3” = “three”))
[1] “one house” “two cars” “three people”
用法3:用回溯引用来插入匹配中的分组

交换句子中第二个单词和第三个单词的顺序

sentences %>%

  • str_replace("([^ ]+) ([^ ]+) ([^ ]+)", “\1 \3 \2”) %>%
  • head(3)
    [1] “The canoe birch slid on the smooth planks.” “Glue sheet the to the dark blue background.”
    [3] “It’s to easy tell the depth of a well.”
    练习

(1) 使用反斜杠替换字符串中的所有斜杠。
str_replace_all(“past/present/future”, “/”, “\\”)

(2) 使用 replace_all() 函数实现 str_to_lower() 函数的一个简单版。
replacements <- c(“A” = “a”, “B” = “b”, “C” = “c”, “D” = “d”, “E” = “e”, “F” = “f”, “G” = “g”, “H” = “h”, “I” = “i”, “J” = “j”, “K” = “k”, “L” = “l”, “M” = “m”, “N” = “n”, “O” = “o”, “P” = “p”, “Q” = “q”, “R” = “r”, “S” = “s”, “T” = “t”, “U” = “u”, “V” = “v”, “W” = “w”, “X” = “x”, “Y” = “y”, “Z” = “z”)
lower_words <- str_replace_all(words, pattern = replacements)
head(lower_words)

(3) 交换 words 中单词的首字母和末尾字母,其中哪些字符串仍然是个单词?
swapped <- str_replace_all(words, “^([A-Za-z])(.*)([A-Za-z])$”, “\3\2\1”)
intersect(swapped, words)
4.5 拆分:str_split() 函数

功能:将字符串拆分为多个片段

用法:

str_split(string, pattern, n = Inf, simplify = FALSE)

str_split_fixed(string, pattern, n)

参数simplify:默认为FALSE,返回的是列表;为TRUE时返回矩阵

将句子拆分成单词

simplify默认为FALSE,返回的是列表

sentences %>% head(3) %> str_split(" ") #在空格处拆开。
[[1]]
[1] “The” “birch” “canoe” “slid” “on” “the” “smooth” “planks.”

[[2]]
[1] “Glue” “the” “sheet” “to” “the” “dark”
[7] “blue” “background.”

[[3]]
[1] “It’s” “easy” “to” “tell” “the” “depth” “of” “a” “well.”

simplify为TRUE时返回矩阵

sentences %>% head(3) %>% str_split(" ", simplify = TRUE)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] “The” “birch” “canoe” “slid” “on” “the” “smooth” “planks.” “”
[2,] “Glue” “the” “sheet” “to” “the” “dark” “blue” “background.” “”
[3,] “It’s” “easy” “to” “tell” “the” “depth” “of” “a” “well.”

因为字符向量的每个分量会包含不同数量的片段,所以 str_split() 会返回一个列表。如果拆分的是长度为 1 的向量,那么只要简单地提取列表的第一个元素即可,.[[1]]的功能类似于head(1)

“a|b|c|d” %>%

  • str_split("\|") %>%
  • .[[1]] #[[是取子集函数[的变体,只提取单个元素,并丢弃名称
    [1] “a” “b” “c” “d”
    参数n:表示拆分的片段数,默认为Inf,即返回所有片段还可以设定拆分片段的最大数量:

fields <- c(“Name: Hadley: baf”, “Country: NZ”, “Age: 35”)

拆分成2段,返回为矩阵

fields %>% str_split(": ", n = 2, simplify = TRUE)
[,1] [,2]
[1,] “Name” “Hadley: baf”
[2,] “Country” “NZ”
[3,] “Age” “35”
参数pattern:除了模式,你还可以用boundary()来匹配字符、单词、行和句子的边界,以这些边界来拆分字符串。

x <- “This is a sentence. This is another sentence.”
str_split(x, " ")[[1]]
[1] “This” “is” “a” “sentence.” “This” “is” “another” “sentence.”
str_split(x, boundary(“word”))[[1]]
[1] “This” “is” “a” “sentence” “This” “is” “another” “sentence”

用boundary(“word”)的拆分效果比" "更灵活,前者结果中只有单词,

后者
结果中还有.
4.6 定位匹配内容:str_locate()

功能:定位模式在字符串中的位置。可以返回每个匹配的开始位置和结束位置。

用法:

str_locate(string, pattern)

str_locate_all(string, pattern)

fruit <- c(“apple”, “banana”, “pear”, “pineapple”)
str_locate(fruit, “a”)
start end
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 5 5

  1. 其他类型的模式
    以下3个函数是同一类型函数,都使用修饰函数控制匹配行为

5.1 regex() 函数

当使用一个字符串作为模式时, R 会自动调用 regex() 函数对其进行包装。

正常调用:当所有参数都为默认设置时,简写为仅字符串(模式)

str_view(fruit, “nana”)

上面形式是以下形式的简写:当需要修改默认参数时,就需要写出regex()函数

str_view(fruit, regex(“nana”))
用法:regex(pattern, ignore_case = FALSE, multiline = FALSE, comments = FALSE, dotall = FALSE, …)

参数:后面这几个参数的默认设置都是FALSE,也就是说,当它们都是FALSE时即为我们前面所学,regex()也可以简写为仅字符串(模式),只是前面学习时未写出默认参数而已,换言之,如果这些参数为TRUE,那就是不同的意思,可以通过修改参数来控制具体的匹配方式

ignore_case(忽略字母大小写):默认为FALSE,匹配时字母区分有大小写。当 ignore_case = TRUE 时,忽略字母大小写,既可以匹配大写字母,也可以匹配小写字母,它总是使用当前的区 域设置:

bananas <- c(“banana”, “Banana”, “BANANA”)

默认区分大小写,只能匹配到第1个字符串

str_view(bananas, “banana”)

不区分大小写,3个字符串都能匹配到

str_view(bananas, regex(“banana”, ignore_case = TRUE))
multiline(多行):默认为FALSE,即没有多行的说法, ^ 和 $ 从完整字符串的开头和末尾开始匹配。当 multiline = TRUE 时,可使 ^ 和 $ 从每行的开头和末尾开始匹配:

x <- “Line 1\nLine 2\nLine 3”

默认只能从完整字符串的开头开始匹配,即只能匹配到第1个Line

str_extract_all(x, “^Line”)[[1]]
[1] “Line”

^可以从每行的开头开始匹配,即3个Line都能匹配到

str_extract_all(x, regex("^Line", multiline = TRUE))[[1]]
[1] “Line” “Line” “Line”
comments(注释):如果为TRUE,可以在复杂的正则表达式中加入注释和空白字符,以便更易理解。匹配时会忽略空格和 # 后面的内容。如果想要匹配一个空格,你需要对其进行转义:"\ ":

phone <- regex("
\(? # 可选的开括号
(\d{3}) # 地区编码
[)- ]? # 可选的闭括号、短划线或空格
(\d{3}) # 另外3个数字
[ -]? # 可选的空格或短划线
(\d{3}) # 另外3个数字
", comments = TRUE)

str_match(“514-791-8141”, phone)
[,1] [,2] [,3] [,4]
[1,] “514-791-814” “514” “791” “814”
dotall:为 TRUE 时 . 可以匹配包括 \n(换行符) 在内的所有字符

5.2 fixed() 函数

功能:可以按照字符串的字节形式进行精确匹配,它会忽略正则表达式中的所有特殊字符,并在非常低的层次上进行操作。这样可以不用进行那些复杂的转义操作,而且速度比普通正则表达式要快很多。

用法:fixed(pattern, ignore_case = FALSE)

microbenchmark::microbenchmark(
fixed = str_detect(sentences, fixed(“the”)), # 用fixed() 函数精确匹配
regex = str_detect(sentences, “the”), # 用regex()函数匹配
times = 20
)

可见,用fixed()函数匹配到的结果要比regex()函数匹配到的少

#> Unit: microseconds
#> expr min lq mean median uq max neval cld
#> fixed 116 117 136 120 125 389 20 a
#> regex 333 337 346 338 342 467 20 b
在匹配非英语数据时,要慎用 fixed() 函数。它可能会出现问题,因为此时同一个字符经常有多种表达方式。如,定义 á 的方式有两种:一种是单个字母 a,另一种是 a 加 上重音符号:

a1 <- “\u00e1”
a2 <- “a\u0301”
c(a1, a2) #可见 a1 和 a2 表示的是同一字符
[1] “á” “a”
a1 == a2 #但比较得到的结果是FALSE
[1] FALSE

这两个字母的意义相同,但因为定义方式不同,所以 fixed() 函数找不到匹配。

str_detect(a1, fixed(a2))
[1] FALSE
5.3 coll() 函数

功能:使用标准排序规则来比较字符串,这在进行不区分大小写的匹配时是非常有效的。

用法:coll(pattern, ignore_case = FALSE, locale = “en”, …)

参数:可以通过设置 locale 参数(区域设置,默认"en"(英语)),以确定使用哪种规则来比较字符。

i <- c(“I”, “İ”, “i”, “ı”)
str_subset(i, coll(“i”, ignore_case = TRUE)) #不区分大小写,默认用英语匹配,i匹配到的是I和i
[1] “I” “i”
str_subset(i, coll(“i”, ignore_case = TRUE, locale = “tr”)) #不区分大小写,区域设置用土耳其语匹配,i匹配到的是İ和i
[1] “İ” “i”
fixed() 和 regex() 函数中都有 ignore_case 参数,但都无法选择区域设置,而coll()函数可以选择区域设置

coll()函数的弱点是速度,因为确定哪些是相同字符的规则比较复杂,与 regex() 和 fixed() 函数相比, coll() 确实比较慢。

5.4 boundary() 函数

功能:匹配(字母、行、句子和单词)边界

用法:boundary(type = c(“character”, “line_break”, “sentence”, “word”), skip_word_none = NA, …)

参数:

type:要检测的边界类型,可以选c(“character”, “line_break”, “sentence”, “word”),即字母、行、句子和单词,前面例子中用到的是匹配单词边界。

x <- “This is a sentence.”
str_extract_all(x, boundary(“word”))
[[1]]
[1] “This” “is” “a” “sentence”
练习

(1) 如何找出包含 \ 的所有字符串?分别使用 regex() 和 fixed() 函数来完成这个任务。

str_subset(c(“a\b”, “ab”), “\\”)
[1] “a\b”
str_subset(c(“a\b”, “ab”), fixed("\")) #尽管fixed()函数可以忽略正则表达式中的所有特殊字符,但书写字符串使还是应该注意特殊字符的特殊含义,比如\表示转义。
[1] “a\b”
writeLines(“a\b”)
a\b

(2) sentences 数据集中最常见的 5 个单词是什么?

tibble(word = unlist(str_extract_all(sentences, boundary(“word”)))) %>% # 以单词为边界提取出句子中的所有单词
mutate(word = str_to_lower(word)) %>% # 将单词中的大写转化为小写
count(word, sort = TRUE) %>% # 以单词分组进行计数,并倒序排
head(5) # 选出前5个

A tibble: 5 x 2

word n

1 the 751
2 a 202
3 of 132
4 to 123
5 and 118

  1. 正则表达式的其他应用
    R 基础包中有两个常用函数,它们也可以使用正则表达式。

6.1 apropos() 函数

功能:通过(部分)名称查找对象,可以在全局环境空间中搜索所有可用对象。当不能确切想起函数名称时,这个函数特别有用:

用法:

apropos(“replace”)
[1] “%+replace%” “.rs.registerReplaceHook” “.rs.replaceBinding”
[4] “.rs.rpc.replace_comment_header” “replace” “replace_na”
[7] “replacements” “setReplaceMethod” “str_replace”
[10] “str_replace_all” “str_replace_na”
“theme_replace”
6.2 dir() 函数

功能:可以列出一个目录下的所有文件

用法:

dir() 函数的 patten 参数可以是一个正则表达式,此时它只返回与这个模式相匹配的文件名。

返回当前目录中的所有CSV文件

head(dir(pattern = “\.csv$”))
[1] “diamonds.csv”

  1. stirngi
    stringr 建立于 stringi 的基础之上。

stringr 非常容易学习,因为它只提供了非常少的函数(只有42个)

与 stringr 不同, stringi 的设计思想是尽量全面,几乎包含了我们可以用到的所有函数(有 234 个函数)。

练习

(1) 找出可以完成以下操作的 stringi 函数。

a. 计算单词的数量。 #用stri_count_words()函数

stri_count_words(head(sentences))
[1] 8 8 9 9 7 7

b. 找出重复字符串。 #用stri_duplicated()函数

stri_duplicated(c(“the”, “brown”, “cow”, “jumped”, “over”, “the”, “lazy”, “fox”))
[1] FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE

c. 生成随机文本。

stri_rand_strings(4, 5) #用stri_rand_strings()生成随机字符串
[1] “BabVd” “ozkiF” “PtBxp” “BRy6A”
stri_rand_shuffle(“The brown fox jumped over the lazy cow.”) #用stri_rand_shuffle()打乱顺序
[1] “ojr mty.eTnowveo zo fbwe pulchhxed ar”

(2) 如何控制 stri_sort() 函数用来排序的语言设置?

通过区域设置

string1 <- c(“hladny”, “chladny”)
stri_sort(string1, locale = “pl_PL”)
[1] “chladny” “hladny”
stri_sort(string1, locale = “sk_SK”)
[1] “hladny” “chladny”

r gsub substr 字符串处理 r去掉双引号相关推荐

  1. php 去掉转义引号的反斜杠,PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠...

    PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠 通过AJAX传到PHP的json字符串有时候加上反斜杠"\"来转义,PHP处理时需要先去掉反斜杠,然后再json_dec ...

  2. powerdesigner mysql 反引号,String字符串去掉双引号

    public static String stringReplace(String str) { //去掉" "号 String str= str.replace("\& ...

  3. C# json解析字符串总是多出双引号_Python小白必备知识:Python字符串详解

    若干个字符的集合就是一个字符串(String).Python 中的字符串必须由双引号" "或者单引号' '包围,具体格式为: "字符串内容" '字符串内容' 字 ...

  4. php echo 双引号,php字符串单引号和双引号的区别

    php字符串单引号和双引号的区别 在PHP中,字符串的定义可以使用英文单引号' ',也可以使用英文双引号" ". 一般情况下两者是通用的,但双引号内部变量会解析,单引号则不解析. ...

  5. 好程序员web前端分享使用JavaScript正则表达式如何去掉双引号

    为什么80%的码农都做不了架构师?>>>    好程序员web前端分享使用JavaScript正则表达式如何去掉双引号,最近接了一个项目,项目需求需要用js正则表达式过滤掉页面文本域 ...

  6. 字符串处理--去除首尾双引号

    项目场景: 使用shell脚本处理带有双引号的文本 问题描述: 数据示例 "{""_index"":""uke_device_op ...

  7. 好程序员分享使用JavaScript正则表达式如何去掉双引号

    好程序员分享使用JavaScript正则表达式如何去掉双引号最近接了一个项目,项目需求需要用js正则表达式过滤掉页面文本域中值得双引号,其实解决办法很简单,下面把我写的代码分享给大家,有同样需求的朋友 ...

  8. 2021-03-04 mysql in里加个参数就查不到??是JSON_EXTRACT导致的,用JSON_UNQUOTE()去掉双引号就正常了

    mysql in里加个参数就查不到??是JSON_EXTRACT返回值带引号导致的,用JSON_UNQUOTE()去掉双引号就正常了 #JSON_UNQUOTE去掉双引号就正常了 SELECT p.* ...

  9. IntelliJ idea——》JSON字符串,自动转义双引号

    版权声明:本文为博主原创文章,无需授权即可转载,甚至无需保留以上版权声明,转载时请务必注明作者. https://blog.csdn.net/weixin_43453386/article/detai ...

最新文章

  1. 链表题目总结(第一篇)
  2. 米哈游蔚来领投“人造太阳”项目!首轮融资4亿,北大物理系校友初创企业:走高温超导路线...
  3. 协程asyncio_Python 异步模块 asyncio 中的协程与任务
  4. 物流行业应用虚拟化解决方案
  5. 作者:李俊清,山东农业大学副教授。
  6. 【Animation】 使用handler和Runnable实现某一个控件的抖动效果
  7. 检查oracle安装必须包,Linux安装oracle11gR2官方步骤
  8. awk 系列Part7:awk 怎么从标准输入(STDIN)读取输入
  9. linux下 复制文件显示进度 alias cp
  10. 支持android11的画质修改器,pubgtool画质修改器
  11. 【CAD】机械类制图实用功能总结
  12. java请输入第一个人,Java-每日编程练习题③
  13. 怎么样在家拍出好看的证件照?标准证件照拍摄技巧分享
  14. 论文笔记:Controlling Decoding for More Abstractive Summaries with Copy-Based Networks
  15. HBase进化之从NoSQL到NewSQL,凤凰涅槃成就Phoenix 1
  16. 手机实现人体扫描建模 快速生成全彩3D人像模型
  17. [git]tig的安装及使用
  18. 学习汇编语言Day05-Cheat Enginee(CE)使用指南
  19. Ubuntu20.4 ROS2 foxy movelt2
  20. SD卡检测插入卡槽方案

热门文章

  1. matlab 图像连通域,matlab二值图像连通域
  2. CMD打开方式以及Dos的基本命令
  3. hdu1398(母函数模板题)
  4. 学计算机找对象容易吗,这4个大学专业单身率最高,找到对象很不容易,一直单身到毕业...
  5. 【个人笔记】SQL操作基础
  6. 【轻聊-前端】编程是什么?
  7. Leonard ai 画明代皇帝肖像
  8. 《眨眼之见》、机器学习、名教与刑名学
  9. Linux乒乓球游戏,python使用pygame实现笑脸乒乓球弹珠球游戏
  10. ABAP 关键字:SPLIT