3.1 使用 grep、sub、gsub 进行搜索和替换

3.1.1 问题

你想要搜索或替换字符串中特定的文本。

3.1.2 方案

两个常用字符串搜索函数 grep()grepl()。两个常用字符串替换函数 sub()gsub()。它们都是向量化操作,会应用到输入字符向量的每一个元素中。

3.1.2.1 文本搜索

grep()grepl() 函数输入的第一个参数都是带有正则表达式的字符串或者固定的字符串(需要设定选项 fixed=TRUE ),它们的不同之处是前者返回匹配的索引或值向量,而后者返回一个逻辑向量。

下面通过简单的例子理解它们的用法和区别:从小写字母向量中搜索 c

  1. grep("c", letters)
  2. #> [1] 3
  3. grepl("c", letters)
  4. #> [1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
  5. #> [9] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  6. #> [17] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  7. #> [25] FALSE FALSE

grep() 函数设定选项 value=TRUE 可以返回匹配的值。

  1. grep("c", letters, value = TRUE)
  2. grep("c", c("dog", "cat"), value = TRUE)

正则表达式提供了一种表达字符模式的强大方式(详情查看 ?regex),我们可以将它应用于文本的搜索中。例如,我们想搜索字符向量中有4个数字连续出现的字符:

  1. grep("\\d{4}", c("This will not match", "2018-04-11, This will match"))
  2. #> [1] 2

3.1.2.2 文本替换

大部分情况下我们不仅仅想搜索到文本,而且还想要在搜索的基础上进行替换,这可以通过 sub()gsub() 函数实现。这两个函数参数是一样的,第一个参数是搜索模式,第二个参数是替换模式,第三个参数是要操作的字符向量。两个函数的区别是前者只会替换字符串中第一个匹配的模式,而 gsub()gglobal 的缩写)会替换字符串中所有匹配模式。

例如,我们想要将字符向量中的年份全部替换为 2019。

  1. sub(pattern = "\\d{4}", replacement = "2019", x = c("This will not match",
  2. "2018-04-11, 2017-04-11", "2018-04-12"))
  3. #> [1] "This will not match" "2019-04-11, 2017-04-11"
  4. #> [3] "2019-04-12"
  5. gsub(pattern = "\\d{4}", replacement = "2019", x = c("This will not match",
  6. "2018-04-11, 2017-04-11", "2018-04-12"))
  7. #> [1] "This will not match" "2019-04-11, 2019-04-11"
  8. #> [3] "2019-04-12"

要操作的对象第二个元素包含2个可以匹配的模式,使用 sub() 只会将第一个替换为 2019,而使用 gsub() 会将所有能够匹配的模式都替换为 2019。