1 字符串
字符串的打印形式与其本身的内容是不相同的,因为打印形式中会显示出转义字符。如果要查看字符串的初始内容,可以使用writeLines()
函数。
字符串长度:str_length()
字符串组合:str_c()
,可以用sep参数控制字符串的分隔方式;如果想将字符向量合并为字符串,可以用collapse参数;该函数是向量化的,可以自动循环短向量,使得其与最长的向量具有相同的长度;如果希望输出缺失值为“NA”,可使用str_replace_na()
字符串取子集:str_sub()
,包括字符串参数和start、end参数(标识子串的位置)
转换大小写:转小写str_to_lower()
,转大写str_to_upper()
或str_to_title()
字符串排序:str_sort()
和str_order()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20> (x <- c("\''", "\\", "a"))
[1] "''" "\\" "a"
> writeLines(x)
''
\
a
> str_c("x", "y", "z", sep = ',') #组合两个或更多的字符串
[1] "x,y,z"
> str_c(c("x", "y", "z"), collapse = ", ") #将字符向量合并为字符串
[1] "x, y, z"
> x <- c("abc", "efg", NA)
> str_c("|-", str_replace_na(x), "-|")
[1] "|-abc-|" "|-efg-|" "|-NA-|"
> x <- c("Apple", "Pear","Banana")
> str_sub(x, 1, 1) <- str_to_lower(str_sub(x, 1, 1))
> x
[1] "apple" "pear" "banana"
> str_sort(x, locale = "en")
[1] "apple" "banana" "pear"
2 正则表达式
^
:从字符串开头进行匹配$
:从字符串末尾进行匹配.
:匹配任意字符(除了换行符)\d
:匹配任意数字\s
:匹配任意空白字符[abc]
:匹配a、b或c[^abc]
:匹配除abc外的任意字符?
:0次或1次+
:1次或多次*
:0次或多次{n}
:匹配n次{n,}
:匹配n次或更多次{,m}
:最多匹配m次{n,m}
:匹配n到m次1
2
3
4
5
6
7
8
9
10
11
12> sub("^a", "", x)
[1] "pple" "pear" "banana"
> sub("a$", "", x)
[1] "apple" "pear" "banan"
> sub("a.c", "", c("abcd", "sdacd"))
[1] "d" "sdacd"
> sub("[ab]", "", c("abcd", "dcba"))
[1] "bcd" "dca"
> sub("[^ab]", "", c("abcd", "dcba"))
[1] "abd" "cba"
> sub("a*b", "", c("aadcd", "dcaaaba"))
[1] "aadcd" "dca"
转义符号的字符串表达:利用反斜杠\
去除某些字符的特殊含义,如匹配.
这个符号,正则表达式是\.
,该表达式的字符串写作“\\.”
;而如果要匹配\
这个字符,其正则表达式是\\
,该表达式的字符串则写作“\\\\”
!
1 | > dot <- "\\." |
3 工具
匹配检测:str_detect()
确定一个字符向量能否匹配一种模式,返回逻辑向量可以计算总数或者平均数str_subset()
通过逻辑取子集str_count()
返回字符串中匹配的数量1
2
3
4
5
6
7
8
9
10
11
12> x
[1] "apple" "pear" "banana"
> str_detect(x, "e")
[1] TRUE TRUE FALSE
> sum(str_detect(words, "^t"))
[1] 65
> str_subset(words, "x$")
[1] "box" "sex" "six" "tax"
> str_count(x, "a")
[1] 1 1 3
> mean(str_count(words, "[aeiou]")) #平均来看,每个单词中有多少个元音字母?
[1] 1.991837
提取匹配内容:str_extract()
提取匹配到的实际文本,得到第一个匹配。str_extract_all()
得到所有匹配,返回列表,设置simplify = TRUE
则会返回一个矩阵。
分组匹配:str_match()
给出每个匹配的独立分组,返回一个矩阵。str_match_all()
返回每个字符串的所有匹配,返回一个列表。
如果数据是保存在tibble 中的,那么使用tidyr::extract()
会更容易,这个函数的工作方式与str_match()
函数类似,只是要求为每个分组提供一个名称,以作为新列放在tibble中。
1 | > x <- c("a", "a b", "a b c") |
替换匹配内容:str_replace()
和str_replace_all()
可以使用新字符串替换匹配内容
拆分:str_split()
可以将字符串拆分为多个片段,返回一个列表,设置simplify = TRUE
返回一个矩阵。还可以设定拆分片段的最大数量;除了模式,还可以通过字母、行、句子和单词边界(boundary()
函数)来拆分字符串。
定位匹配内容:str_locate()
和str_locate_all()
1 | > x <- c("apple", "pear", "banana") |
4 其他类型的模式
4.1 regex()函数
当使用一个字符串作为模式时,R会自动调用regex()
函数对其进行包装,调用该函数时,可以通过设置一些参数来控制具体的匹配方式:ignore_case = TRUE
既可以匹配大写字母,也可以匹配小写字母,它总是使用当前的区域设置。multiline = TRUE
可以使得^
和$
从每行的开头和末尾开始匹配,而不是从完整字符串的开头和末尾开始匹配。comments = TRUE
可以在复杂的正则表达式中加入注释和空白字符,以便更易理解。匹配时会忽略空格和# 后面的内容。dotall = TRUE
可以使得.
匹配包括\n 在内的所有字符。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25> bananas <- c("banana", "Banana", "BANANA")
> str_replace_all(bananas, regex("b|a|n", ignore_case = TRUE), "*")
[1] "******" "******" "******"
> x <- "Line 1\nLine 2\nLine 3"
> writeLines(x)
Line 1
Line 2
Line 3
> str_extract_all(x, "^Line")[[1]]
[1] "Line"
> str_extract_all(x, regex("^Line", multiline = TRUE))[[1]]
[1] "Line" "Line" "Line"
> 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"
4.2 fixed()和coll()函数
fixed()
函数可以按照字符串的字节形式进行精确匹配,它会忽略正则表达式中的所有特殊字符,并在非常低的层次上进行操作。这样可以让你不用进行那些复杂的转义操作,而且速度比普通正则表达式要快很多。但在匹配非英语数据时,要慎用fixed() 函数。它可能会出现问题,因为此时同一个字符经常有多种表达方式。
coll()
函数使用标准排序规则来比较字符串,这在进行不区分大小写的匹配时是非常有效的。注意,可以在coll() 函数中设置locale 参数,以确定使用哪种规则来比较字符。其弱点是慢。
- 本笔记参考书目:Hadley Wickham的《R数据科学》