替换文本中大于 5 位的数字

replace number greater than 5 digits in a text

a <- c("this is a number 9999333333 and i got 12344")

如何将大于 5 位的数字替换为“X”

预期输出:

"this is a number 99993XXXXX and i got 12344"

我试过的代码:

gsub("(.{5}).*", "X", a)

您可以将 gsub 与 PCRE 正则表达式一起使用:

(?:\G(?!^)|(?<!\d)\d{5})\K\d

参见regex demo。详情:

  • (?:\G(?!^)|(?<!\d)\d{5}) - 上一个成功匹配的结尾 (\G(?!^)) 或 (|) 前面没有数字 ((?<!\d)) 的位置,然后是任何五位数
  • \K - 匹配重置运算符丢弃目前匹配的所有文本
  • \d - 一个数字。

参见R demo

a <- c("this is a number 9999333333 and i got 12344")
gsub("(?:\G(?!^)|(?<!\d)\d{5})\K\d", "X", a, perl=TRUE)
## => [1] "this is a number 99993XXXXX and i got 12344"
gsubfn 包中的

gsubfn 类似于 gsub 除了替换字符串可以是输入捕获组并输出匹配项替换的函数。该函数可以选择用公式表示法表示,就像我们在这里所做的那样。

正则表达式(\d{5})匹配并捕获5位数字,(\d+)匹配并捕获其余数字。两个捕获组被送入函数并粘贴回一起,除了第二个中的每个字符被替换为 Xr"{...}" 是 R 4.0 中引入的字符串文字表示法,它消除了必须使用双反斜杠来表示字符串文字中的反斜杠的情况。

library(gsubfn)

gsubfn(r"{(\d{5})(\d+)}", ~ paste0(x, gsub(".", "X", y)), a)
## [1] "this is a number 99993XXXXX and i got 12344"

如果我们用正则表达式替换第一个参数 r"{(\d{2})(\d{4,})}" 那么它将替换除前两位以外的所有数字,前提是至少有 6 位数字。

另一种方法,不使用 gsub 替换文本中大于 5 位的数字 是用 strsplit 拆分字符串,测试是否只有数字并组合 substrstrrep:

paste(lapply(strsplit(a, " ")[[1]], function(x) {
  if(!grepl("\D", x)) {
    paste0(substr(x, 1, 5), strrep("X", pmax(0, nchar(x)-5)))
  } else {x}}), collapse = " ")
#[1] "this is a number 99993XXXXX and i got 12344"

要在大于 5 位数字的前 2 位数字后替换 X:

paste(lapply(strsplit(a, " ")[[1]], function(x) {
  if(!grepl("\D", x) & nchar(x) > 5) {
    paste0(substr(x, 1, 2), strrep("X", pmax(0, nchar(x)-2)))
  } else {x}}), collapse = " ")
#[1] "this is a number 99XXXXXXXX and i got 12344"