【问题标题】:Using gsub to replace matches with same number of characters使用 gsub 替换具有相同字符数的匹配项
【发布时间】:2022-01-29 16:05:24
【问题描述】:

是否可以使用 gsub 将匹配的每个字符替换为另一个字符?我已经阅读并尝试了很多问题的解决方案,但都没有成功,因为它们对所使用的示例非常具体。有些看起来很有希望但最终没有让我到达那里

gsub-replace-regex-match-with-regex-replacement-string

replace-pattern-with-one-space-per-character-in-perl

我正在寻找的是执行以下操作的一般方法。我有一个正则表达式列表,我将它们组合成一个形式的正则表达式

pattern <- "[0-9]{3,}|[a-z]{3,}|..."

给定一个字符串,例如

x <- "1234 abc 12 a 123456"

我想从 gsub 取回字符串,其中匹配的每个字符都替换为 #

"#### ### 12 a ######"

而不是

"# # 12 a #"

我使用 gsub 并将 perl arg 设置为 TRUE,并尝试使用在线正则表达式工具,使用 \G 和外观等工具,但我无法弄清楚。

我正在寻找一种方法来使用gsub 执行此操作(我意识到以其他方式很容易做到这一点)的原因是将其用作审查某些单词和匹配项的方法,例如日期、电话号码和dplyr 管道中的电子邮件地址。我的函数工作正常,除了任何替换都是固定的,我想替换每个匹配的字符,而不是每个匹配的子字符串。

filter_words <- function(.data, .words, .replacement, ...) {
  .data %>% dplyr::mutate(
    dplyr::across(
      c(...),
      ~ gsub(
          paste0("\\b", .words, collapse = "|\\b"),
          .replacement, .,
          ignore.case = TRUE, perl = TRUE
      )
    )
  )
}

我确实尝试使用一个名为 mgsub 的包来提供它提供的 mgsub_censor 函数。这确实有效,但它比我已经拥有的要慢几个数量级,因此对于大型数据集来说并不实用。

我确实尝试创建一个自定义 gsub 函数,该函数能够接受一个函数(该函数可以返回一个包含与每个匹配项相同数量的字符组成的字符串)作为替换参数。它适用于单个字符串,但无法在管道中工作。

【问题讨论】:

  • 我用 perl 标记,因为我使用 gsub 和 perl=TRUE。
  • 您需要在开始时说明您用于替换的规则。唯一的证据是您想将"1234 abc 12 a 123456" 转换为"#### ### 12 a ######"。我可以想到许多可以实现这一点的规则: 两个如下: 1. 将除空格以外的 3 个或更多字符的字符串中的每个字符转换为 '#'; 2) 1. 将3个或更多字母或4个或更多数字的字符串中的每个字符转换为'#'。请编辑澄清。
  • @CarySwoveland - 我认为从最初的问题很清楚:“......用另一个字符替换匹配的每个字符?”。无论如何,我已经在示例中添加了我想要的内容。

标签: r regex gsub


【解决方案1】:

您可以在str_replace_all 中传递一个函数并使用strrep 重复# 符号n 次。

x <- "1234 abc 12 a 123456"
pattern <- "[0-9]{3,}|[a-z]{3,}"

stringr::str_replace_all(x, pattern, function(m) strrep('#', nchar(m)))
#[1] "#### ### 12 a ######"

【讨论】:

  • 请问如何添加 gsub 的 ignore.case 等价物?
  • stringr::str_replace_all(x, regex(pattern, ignore_case = TRUE), function(m) strrep('#', nchar(m)))
  • 还不错,只比用固定替换慢10倍。
猜你喜欢
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
相关资源
最近更新 更多