传统数据分析的对象多是数字而非文字。这主要是受制于分析技术与相关工具的发展水平。实际上,人类行为的许多内容是以文字、语音、表情等难以完全数字化的方式存在。如何扩大数据分析的范畴,将分析对象拓展至文本数据、音频数据和视频数据,是近些年来数据分析领域的热门议题。这里仅限对利用 R 语言进行文本数据的基础处理和统计分析进行简单介绍,但很多内容也适用于其他软件。
R 基础安装包中内置了一些字符串处理函数,能在很大程度上满足基本使用需求,也是进一步学习其他 R 包中相关字符串函数的基础。这里择要进行简单介绍。
函数名称 | 功能 |
---|---|
nchar(x) |
计算向量 x 中的字符数、字节数或宽度 |
substr(x, start, end) |
指定起始位置截取子字符串 |
grep(pattern, x) |
检索向量 x 中的元素是否包含指定的模式,并返回其在 x 中的序位 |
sub(pattern, replacement, x) |
替换向量x 中的指定模式 |
strsplit(x, split) |
指定位置切割字符串 |
paste(x, y, sep = "") |
拼接向量 x 与 y |
toupper(x) |
将 x 中的所有英文字母转为大写(upper case) |
tolower(x) |
将 x 中的所有英文字母转为小写(lower case) |
cat(x, y) |
连接向量并定制化输出至屏幕或文件, cat 是英文 concatenate(串联、合并)的缩写 |
以下通过一些实例说明上述函数的使用方式。诸多演示将使用如下的简单汉语字符向量。
x <- c("北京大学社会学系", "清华大学心理学系", "南开大学社会心理学系")
先看nchar()
。
nchar(x)
显示为各元素中包含的字符个数。这看似简单,实则不然。nchar()
的用法为:
nchar(x, type = "")
其中,type
参数有三个选项:
chars
(字符数),1个英文单词、数字或汉字计1字符bytes
(字节),1个英文单词或数字为计1字节,1个汉字计2字节width
(宽度),将字符串转为等宽字体 ^[等宽字体(monospaced font)是指字符宽度相同的电脑字体,字符宽度不尽相同的电脑字体则称为比例字体(proportional font)。编程代码常使用的是等宽字体。]后所占的列数,通常与bytes
的计算方式相同
所以,如果输入
nchar(x, type = "bytes")
即可看到不同结果。
substr()
函数的结果一目了然:
substr(x, 1, 4)
grep()
函数实际上通常要匹配其他函数来用,这里只做简单示例:
grep("大学", x)
这表示 x 向量中的前3个元素均包含“大学”这一字符。
sub()
的作用是替换,其中sub 是英文 substitute(替换)的缩写。
sub("大学", "University", x)
paste()
可将若干向量的横向拼接,其用法为:
paste (A, B, sep = " ", collapse = NULL)
其中,
A
、B
表示等拼接的向量,可拓展至多个向量sep
表示连接各向量中各元素的连接符collapse
表示将各向量拼接为一个向量的连接符
只看解释很难让人明白这两个参数的功能。细看以下示例:
paste("南开大学", "社会心理学系", sep = "-")
paste("南开大学", "社会心理学系", sep = "**")
paste("南开", c("社会学系", "社会心理学系", "经济学系"), sep = "大学")
paste(LETTERS[1:5], letters[1:5], sep = "-")
paste(LETTERS[1:5], letters[1:5], sep = "-", collapse = " | ")
前三例非常直观,值得注意的是后两例,请体会sep
和collapse
这两个参数的不同功能。
从示例可看出,sep
参数用于横向拼接向量,即把paste(A, B, sep = "")
中的第一个向量和第二个向量按元素顺序逐对拼起来,而collapse
是把一个向量内部所有元素按一个分隔符拼接为单个字符串。按 R 的自动扩展原则,若两个向量长度不一,短向量会被扩展到长向量的长度,再去拼接。同时,sep
返回的仍然是一个向量,每一元素是所拼接向量中的相应位置上的元素拼接而成;而collapse
把所有字符向量“坍缩”为一个字符串,这正是 collapse 的英文本意。
paste()
还经常与cat()
配合使用,以定制输出形式,例如:
paste("我是爱南开的", "周恩来", sep = "\n")
cat(paste("我是爱南开的", "周恩来", sep = "\n"))
paste()
只执行拼接功能,而显示结果还需要通过cat()
来完成。
touppper()
与tolower()
的功能也非常直观:
toupper(letters[1:5])
tolower(LETTERS[1:5])
这里不再细述。
R 内置的字符串函数还有很多,功能也较齐全。其缺点在于函数命名比较分散,没有统一风格,不利于记忆。另外,在一些复杂字符串的处理上仍有一定欠缺。为此,可调动 stringr 等包中的相关函数加以更为灵活便捷的处理。
绝大多数 stringr 包中的函数都以str_
开头(表示string),下划线后跟着一个动词或其缩写,以指明其功能。以下按字母序列出stringr 包中的重要函数及其功能。
函数名称 | 功能 |
---|---|
str_c() |
拼接多个字符串为单个字符串 |
str_conv() |
更改字符串的编码类型 |
str_count() |
计算字符串中指定模式的字符个数 |
str_detect() |
判断字符串是否包含指定模式 |
str_dup() |
将向量中的各字符串重复自身 n 次 |
str_extract() |
提取字符串中包含的指定模式(匹配一次) |
str_extract_all() |
提取字符串中包含的指定模式(匹配所有) |
str_length() |
计算字符串的长度(即所包含的字符个数) |
str_locate() |
给出指定模式在字符串中的起始位置(输出矩阵) |
str_locate_all() |
给出指定模式在字符串中的起始位置(输出列表) |
str_match() |
判断字符串中是否包含指定模式(输出矩阵) |
str_match_all() |
判断字符串中是否包含指定模式(输出列表) |
str_order() |
给出字符串在所处向量中的位置(默认首字母升序) |
str_pad() |
用指定字符填充字符串至指定字符长度 |
str_replace() |
替换字符串中的指定模式(匹配一次) |
str_replace_all() |
替换字符串中的指定模式(匹配所有) |
str_replace_na() |
将表示缺失值的 NA 替换为字符串 "NA" |
str_sort() |
按字符串在所处向量中的位置排序(默认首字母升序) |
str_split() |
根据指定模式切割字符串(输出列表) |
str_split_fixed() |
根据指定模式切割字符串(输出矩阵) |
str_sub() |
指定起始位置截取子字符串 |
str_subset() |
给出所有包含指定模式的字符串 |
str_trim() |
删去字符串首尾处的空白符 |
str_trunc() |
删除部分内容使字符串截为指定宽度 |
str_which() |
给出所有包含指定模式的字符串的位置(输出整数) |
str_wrap() |
设定字符串的段落输出形式 |
str_view() |
网页格式下对指定模式阴影显示(匹配一次) |
str_view_all() |
网页格式下对指定模式阴影显示(匹配所有) |
str_to_upper() |
将字符串中的所有英文字母转为大写(upper case) |
str_to_lower() |
将字符串中的所有英文字母转为小写(lower case) |
str_to_title() |
将字符串中的英文单词转为首字母大写 |
word() |
提取句子中指定位置的单词 |
许多函数通过示例可一目了然,不再细述。少数复杂的函数会细加解释。同时请注意 stringr 字符串函数与 R 基础包中的字符串函数的比较。
展开分析前,请确保已载入 stringr 包。
library(stringr)
str_c()
函数用于横向拼接字符串。
str_c("南开", "大学")
str_c("南开", "大学", sep = "")
str_c("南开", "大学", sep = "-")
可见默认不加空格拼接,也可指定用于拼接的字符。但str_C()
的功能并不局限于此。试看下面的命令:
str_c(LETTERS[1:5], letters[1:5], sep = "-")
str_c(LETTERS[1:5], letters[1:5], collapse = "-")
str_c(LETTERS[1:5], letters[1:5], sep = "-", collapse = " | ")
请结合此例再次明确sep
与collapse
参数的功能。
str_replace_na()
函数将表示缺失值的 NA
替换为字符串 "NA"。试比较以下结果:
na <- c(NA, "A", "B")
na
str_replace_na(na)
str_trunc(string,
width,
side = c("right", "left", "center"),
ellipsis = "...")
trunc是英文 truncate 的缩写,其中
string
:待操纵的字符串width
:截断后的最大宽度side
:指定截断的方向ellipis
:指明被移除位置的替代符号,默认 ...(宽度为3)
str_trunc(x, 4, side = "left")
str_trunc(x, 2, side = "right", ellipsis = "-")
str_trunc(x, 6, side = "center", ellipsis = "XX")
str_dup()
函数用于复制向量中的字符串,dup 是英文 duplicate 的缩写。请观察以下示例。
n <- "南开"
k <- "大学"
nk1 <- c(n, k)
nk1
nk2 <- str_c(n, k)
nk2
str_dup(nk1, 2)
str_dup(nk2, 2)
word()
函数用于提取句子中指定位置的单词,一般要求各单词之间应有空格划分。这一功能在中文领域目前较难有用武之地,因为中文句子的各个单字之间并无英文单词之间的空格,除非人为加入。
Chi <- c("南 开 大 学", "北 京 大 学")
word(Chi, 1, 2)
Eng <- c("He likes cats.", "She hates rats.")
word(Eng, 2)
str_count()
用于计算字符串中包含的字符数。
str_count(x)
str_count(x, "心理学")
str_count()
的功能类似于 R 基础包中的nchar()
函数(number of characters),但nchar()
的功能更全;前者只能用于计算字符数,后者还可用于计算字节数或宽度。
str_detect(x, "心理学")
str_extract(x, "心理学")
str_extract_all(x, "心理学")
str_extract_all(x, "心理学", simplify = TRUE)
str_locate(x, "心理学")
str_locate_all(x, "心理学")
str_replace(x, "学", "xue")
str_replace_all(x, "学", "xue")
str_match(x, "心理学")
str_match_all(x, "心理学")
str_split(x, "大学", n = 2)
str_split(x, "大学", n = 2, simplify = TRUE)
str_split_fixed(x, "大学", n = 2)
str_sub(x, start = 1, end = 4)
str_sub(x, -4, -1)
str_subset(x, "心理学")
str_which(x, "心理")
str_view(x, "学")
str_view_all(x, "学")
str_pad()
函数用于填充字符串,格式如下:
str_pad(string,
width,
side = c("left", "right", "both"),
pad = " ")
其中,
string
:待填充的字符串width
:待填充的最大宽度,长度以字节(byte)计side
:填充方向pad
:用于填充的符号(限1个字节宽度),默认为空格
str_pad(x, 20, side = "left")
注意左边出现的空格。一个汉字占两个字节,故“南开大学社会心理学系”正好20字节,无须填充。再看下例。
str_pad(x, 20, side = "right", pad = "X")
str_order()
和str_sort()
分别用于给出字符串的序位及根据这一序位排序。
str_order(x)
str_sort(x)
str_sort(x, decreasing = TRUE)
str_to_upper()
、str_to_lower()
、str_to_title()
用于英语字母的大小写转换。
Eng <- c("He likes cats.", "She hates rats.")
str_to_lower(Eng)
str_to_upper(Eng)
str_to_title(Eng)
paragraph <- c("R是一个免费、自由且跨平台通用的统计计算与绘图软件,它有Windows、Mac、Linux等版本,均可免费下载使用。R项目(The R Project for Statistical Computing)最早由新西兰奥克兰大学(Auckland University)的Robert Gentleman(1959-) 和 Ross Ihaka(1954-) 开发,故软件取两人名字的首字母命名为R。")
str_wrap(paragraph, width = 30, indent = 4)
此时可见每40个字节即被切分为一行(增加了换行符\n),但并未分行显示;indent = 4
表示首先缩进4字节。在str_wap()
的基础上使用基础命令cat()
即可达到合并成段落。
cat(str_wrap(paragraph, width = 40, indent = 4))
空白符
空白符(white space)并不仅仅指空格(Space ),还包括制表符、回车符、换行等。
常用空白符类型
名称 | 符号 |
---|---|
空格符(space) | |
水平制表符(horizontal tab) | \t |
垂直制表符(vertical tab) | \v |
换行符(line feed) | \n |
回车符(carriage return) | \r |
注意表格空格符对应的符号为空,这并不表示没有符号,而是表示空格符号。请参考此两者的区别:""
和" "
,前一对双引号中无任何符号,后一对双引号中有一个空格。
同时注意换行与回车的本质并不相同,它们源自传统的电传打字机。所谓回车是让打字机把打印头“回归”(return)到最初始位置(左边界处),换行则指让打字机把纸向下移一行。Unix系统中每行结尾只有“换行”,Windows系统里每行结尾是“回车 + 换行”,Mac系统里每行结尾是“回车”。这会造成不同系统下的文本文档在跨系统读取时出现格式变异问题。Word软件中的“回车”,其实也是回车 + 换行的组合。
为更好地说明str_trim()
的功能,下面结合一个初步的网页爬虫实例进行示例。爬虫时经常会遇到要爬取多个链接中的相关内容,通常的做法是将所有链接保存为一个文件,然后再使用特定的循环语句,对每一个链接执行相同的操作。这里的第一步就是如何简洁高效地获取相关链接。这里以我国中央人民政府门户网站(即通常所谓“中国政府网”网站)上提供的政府工作报告页面作为示例页面。在
http://www.gov.cn/guowuyuan/baogao.htm
这个链接中,给出自1954年以来的历届政府工作报告。每个报告均以单独链接的方式存在,点击后即可阅读相关内容。若要一次性爬取所有报告内容,首先需要获得每年政府工作报告的链接地址。网络爬虫涉及基础网页结构知识和相关软件包的学习,这里暂不展开,只结合 rvest 等 R 包的相关函数展示相关说明,以说明str_trim()
的功能(请确保联网以执行相关功能,并确定已安装 rvest 包)。
library(xml2)
library(rvest)
library(stringr)
url <- "http://www.gov.cn/guowuyuan/baogao.htm"
reports <- read_html(url)
links <- reports %>%
html_nodes(".history_report a") %>%
html_attr("href")
head(links)
这里的 links
对象已储存了所有49个政府工作报告(1954--2017)的详细链接。然后细分析每个“链接”,发现其结尾都有两个空白符:\r\n
。这其实正是“回车 +换行”的意思。要让 R 准确读取链接,这两个空白符应当删去。此时即可使用str_trim()
函数如下:
links <- str_trim(links)
head(links)
此时即可显示“纯净”的链接地址,方便进行下一步的工作。
最后,stringr 提供了三个文本数据,以供练习相关命令:sentences
, fruit
, words
。加载 stringr 包后直接输入以上单词,回车后即可见到,例如:
stringr::fruit[1:5]
上述示例只展示了 stringr 中的基础函数用法,并未全面展示字符串处理的所有功能与应用。要更有效率地使用这些函数进行文本数据分析,需要进一步了解正则表达式。
正则表达式(regular expression,简称 regex)是用于匹配、搜索和替换文本的字符串 ^[正则表达式听起来很陌生,实际上人们在文件夹中搜索类似包含“会议记录”字段的所有文件、或是在Word软件中一次性替换所有小写的“car”为首字母大写的“Car”单词、一次性把所有数字都转换为Times New Roman字体等操作时,就已在使用类似正则表达式的功能。]。它内置于多种程序语言或软件产品,是一种非严格意义上的“迷你语言”,其功能在于搜索特定模式(pattern)的文字并加以处理(如截取、替换等)。正式表达式在不同程序语言中有着不同的细节规定,但多数规则可跨语言通用。这里就这些通用规则并结合 R 语言的特征进行介绍。想要精通正则表达式需要较长时间,但了解基本的规则并不困难,细节内容可在实际工作需要时再去深究。
正则表达式本身就是由字符构成,但为了达到匹配其他字符的功能,需要对其中一些特定字符的功能加以限定。元字符(metacharacter)就是在正则表达式有特殊含义的字符,每一个元字符能匹配一个位置或一个字符。
正则表达式中有些基本字符被保留用作特殊用途,它们的含义不能从“字面意思”进行理解,且常与其他字符匹配成字符集合,以表达不同的字符类别。
正则表达式中的基础元字符
符号 | 功能 |
---|---|
^ |
匹配字符串的开始位置;放在[] 中则表示反义,即[^aeiou] 表示匹配除了[] 中给定字符集合外的字符 |
$ |
匹配字符串的开始位置 |
. |
匹配除换行符之外的所有字符 |
` | ` |
? 、* 、+ |
限定重复匹配次数,后面详细说明 |
\ |
对下一字符转义;或放在其他字符开头,组合特定的元字符 |
[] |
方括号配对使用,匹配括号内的任意字符 |
() |
圆括号配对使用表示字符组,括号内的字符串作为整体被匹配 |
由于元字符已被赋予特殊含义,因此,如果确实要匹配作为文本字符本身的上述符号,就需要通过转义符来实现。转义符(escape character)其实是一种特殊的元字符,“转义”就是“转换含义”的意思。转义符本身不被当成实体字符,而是起到提醒作用,使其后面的字符表达出特定的含义。不同程序使用的转义符并不相同,通常使用的转义符是反斜杠(捺斜杠)\
。
然而,由于\
本身是元字符,因此在实际使用中会有诸多麻烦。例如,要匹配英文句号.
本身,就不能写成.
,也不能写成\.
。这是因为\
本身会被理解元字符而不是普通的文本字符。只有写成\\.
才能达到匹配目的。试比较:
a <- c("a.\a123", "b.\a456", "c.\a789a", "d.\a")
a
str_view(a, ".")
str_view(a, "\\.")
str_view(a, ".")
时突出显示的是第一个字符,这正是因为.
号起到了元字符的作用。只有转义后才能突出显示.
号本身。而如果输入str_view(a, "\.")
则会出现错误信息。类似地,\\(
会匹配(
,\\)
会匹配)
,其他可类推。
细心的读者应该已经发现,刚才在执行str_view()
命令时,\
以及它后面的第一个字符并没有显示出来。这其实正是因为在\
是一个转义符而不是普通字符,而跟在它后面的字母a
因为并不是有意义的转义符号组合,所以被忽略掉,这其实正是英文 escape(逃离) 的本义。要正确地显示文本数据的内容,可使用 R 基础安装包中的writeLines()
函数。
a0 <- c("a.\a123", "b.\a456", "c.\a789c", "d.\a")
a0
writeLines(a0)
a1 <- c("a.\\a123", "b.\\a456", "c.\\a789c", "d.\\a")
writeLines(a1)
请比较a0
和a1
的结果。如果想要真正呈现带有\
符号的文本,a1
才是正确的写入方式。
那么,如何匹配\
自身呢?思路如下:\
是元字符,需要加以转义,故加上转义符\
,变成\\
;创建\\
这一正则表达式,仍需要前面用\
加以申明;最后,\\\\
才能表示出作为普通文本符号的\
。
str_view(a0, "\\\\")
str_view(a1, "\\\\")
这可能是个特例。好在如此复杂的表达并不多见。
与多数程序语言一样,R 支持预定义的POSIX字符类 ^[POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是国际电气和电子工程师协会(IEEE)为在各种UNIX操作系统上运行的软件而定义的一系列标准的总称。],即通过一些特定字符组合表示一类字符。
符号 | 功能 |
---|---|
[:alnum:] |
任意英文字母及数字,等价于[a-zA-Z0-9] ,其中连字符- 号表示范围区间 |
[:alpha:] |
任意英文字母,等价于[a-zA-Z] |
[:blank:] |
空格(Space)或制表符(Tab),等价于[\t ] ,注意字母t 后有一个空格 |
[:cntrl:] |
任意ASCII控制字符 |
[:digit:] |
任意数字,等价于[0-9] |
[:graph:] |
任意图形字符,包括标点、字母及数字,即[:alnum:]和[:punct:]的集合 |
[:lower:] |
任意小写字母,等价于[a-z] |
[:print:] |
任意可打印字符,即[:alnum:],[:punct:]和[:space:]的集合 |
[:punct:] |
任意英文标点符号,包括 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ { | } ~ ` . |
[:space:] |
任意空白符,包括水平制表符(\t )、垂直制表符(\v )、空格符(space)、换行符(\n )、回车符(\r )、换页符(\f ) |
[:upper:] |
任意大写字母,等价于[A-Z] |
[:xdigit:] |
任意十六进制数字,即0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f ,等价于[0-9a-fA-F] |
正则表达式中也可用一些固定的字符串表达特殊含义,它们均以\
符号开头,通用的模式如下:
符号 | 功能 |
---|---|
\< |
匹配单词的开头位置 |
\> |
匹配单词的结束位置 |
\b |
匹配单词的边界(boundary),即单词开头或结束的位置 |
\B |
匹配非单词开头或结束的位置 |
\d |
匹配任意数字,等价于[:digit:] |
\D |
匹配任意非数字,等价于[^[:digit:]] |
\s |
匹配空白符,等价于[:blank:] |
\S |
匹配非空白符,等价于[^[:blank:]] |
\w |
匹配字符串,等价于[:alnum:] |
\W |
匹配非字符串,等价于[^[:alnum:]] |
\x |
匹配十六进制数字,等价于[:xdigit:] |
当然,由于\
号本身是元字符,因此在 R 中需要加以转义,所以上述模式需要写成形如\\d
的模式。例如:
str_replace_all(a, "\\d", "x")
正则表达式的元字符一次一般只能匹配一个位置或一个字符。若想匹配零个、一个或多个字符时,需要使用限定符,用于指定允许特定字符或字符集重复出现的次数。
符号 | 功能 |
---|---|
{n} |
重复n次 |
{n,} |
重复至少n次 |
{n,m} |
重复至少n次、至多m次 |
? |
重复零次或1次 |
* |
重复零次或多次 |
+ |
重复1次或多次 |
符号 | 功能 |
---|---|
() |
定义子表达式,可使复杂的正则表达式更适合阅读 |
(?=) |
以?= 号后的字符为起点(不包含该字符本身),向前查找匹配的模式 |
(?<=) |
以?<= 号后的字符为起点(不包含该字符本身),向后查找匹配的模式 |
(?!) |
以?<= 号后的字符为起点(不包含该字符本身),向前查找指定模式之外的字符,称为负向前查找 |
(?<!) |
以?<= 号后的字符为起点(不包含该字符本身),向前查找指定模式之外的字符,称为负向后查找 |
负向前查找(negative lookahead)和负向后查找中的“负”,均表示逻辑上的“否”,即对向前查找和向后查找取反义,但查找顺序相同。这也是为什么负查找使用了!
号的原因,它是 R 及许多程序语言中表示“否”的逻辑符号。
library(tibble)
library(rvest)
library(dplyr)
library(stringr)
url <-
"http://www.moe.gov.cn/jyb_zzjg/moe_347/201508/t20150824_202647.html"
cast <- read_html(url, encoding = "UTF-8") %>% html_nodes(".pt105")
http_links <- html_attr(cast, "href")
universitiy_names <- html_text(cast)
unme <- cbind(universitiy_names, http_links) %>% as_tibble()
write.csv("unme.csv")
str_count(unme$universitiy_names, "学院") %>% sum()
unme <- mutate(unme, collage = as.numeric(str_detect(universitiy_names, "学院")),
china = as.numeric(str_detect(universitiy_names, "中国")),
brother = as.numeric(str_detect(unme$universitiy_names, "[()]")),
abbrevs = str_extract(unme$http_links, "(?<=\\.).*(?=\\.e)"))
上述命令中的最后一行,str_extract(unme$http_links, "(?<=\\.).*(?=\\.e)")
表示提取第一个.
号之后、第一个.e
之前的内容。这显然是因为所有教育部直属院校的域名均以.edu.cn
结尾。这是一种“投机取巧”的做法。更为普遍的解法思路应是:如何提取某两个特定位置的.
号之间的内容?就此例而言,就是如何提取第一个.
号与第二个.
号之间的内容(不包括.
号本身)?
实现的方式并不统一。这里提供一种思路。
str_extract(unme$http_links[1:5], "(?<=\\.)([^\\.]+)(?=\\.)")
其中,
?<=\\.
表示从第一个.
号之后进行匹配[^\\.]+
表示至少匹配一个非.
号的字符?=\\.
表示在第二个.
号之前进行匹配()
仅表示运算的优先性,以便阅读
请思考如下语句的结果:
str_extract(unme$http_links[1:5], "(?<=\\.)([^\\.]+)(?=\\.)")
此外,对于形如"http://www.pku.edu.cn/"
这种结构清晰的字符串,也可先将其按规则切割成若干子字符串,然后再提取所需部分。此处按3个.
号将http_links
列切割为4列,再提取第2列即可。示例如下:
str_split_fixed(unme$http_links, "\\.", n = 4)[, 2][1:5]
其中,()
外的第一个方括号[, 2]
表示提取前述结果的第2列,第二个方括号[1:5]
表示只列示前5列结果,以节省空间。
如果一个字符串有若干个相同符号(如这里的.
号),提取第一个和第二个符号之间的内容,直接采用定位匹配的方式是比较方便的。而当所提取内容存在一系列符号中的某两个之间时,可能先切割再提取的方式更容易操作。