【问题标题】:Match regular expression case insensitively, replace with specific case不区分大小写匹配正则表达式,替换为特定大小写
【发布时间】:2016-09-12 11:36:54
【问题描述】:

我正在使用正则表达式来替换一些子字符串。替换值重用匹配的一部分。我想不区分大小写地匹配,但在替换时,我想要匹配的东西的小写版本。

library(stringi)
x <- "CatCATdog"
rx <- "(?i)(cat)(?-i)"
stri_replace_all_regex(x, rx, "{$1}")
# [1] "{Cat}{CAT}dog"

这与我想要的很接近,除了“cat”应该是小写的。也就是说,输出字符串应该是"{cat}{cat}dog"

以下代码不起作用,但它表明了我的意图。

stri_replace_all_regex(x, rx, "{tolower($1)}") 

以下技术确实有效,但它很丑陋,不是很通用,也不是很有效。我的想法是用与我想要的匹配的正则表达式替换正则表达式,而不是替换值(即“cat”而不是“{cat}”)。然后在每个输入字符串中搜索第一个匹配,找到匹配的位置,做一个子字符串替换,然后寻找下一个匹配,直到没有更多的匹配。太可怕了。

x <- "CatCATdog"
rx <- "(?i)((?<!\\{)cat(?!\\}))(?-i)"
repeat{
  detected <- stri_detect_regex(x, rx)
  if(!any(detected))
  {
    break
  }
  index <- stri_locate_first_regex(x[detected], rx)
  match <- tolower(stri_match_first_regex(x[detected], rx)[, 2])
  stri_sub(x[detected], index[, 1], index[, 2]) <- paste0("{", match[detected], "}")
}

我觉得一定有更好的方法。

如何用小写值替换不区分大小写的匹配项?


感谢 cmets 的启发,我发现我正在寻找的东西是“replacement text case conversion”。

【问题讨论】:

  • gsub(rx, "{\\L\\1}", x, perl=TRUE)
  • @user2957945 听起来像是一个答案
  • @ThomasAyoub ;这只是一个简短的评论——我最好把这个留给正则表达式忍者,以防万一我没有意识到的边缘情况等 + Richie 似乎想使用我不使用的 strtingi。
  • @user2957945 看来stringi 不支持大小写转换,所以你不妨把这个写下来作为答案。

标签: regex r


【解决方案1】:

如果您需要执行任何类型的字符串操作,您可以使用gsubfn

> library(gsubfn)
> rx <- "(?i)cat"
> s = "CatCATdog"
> gsubfn(rx, ~ paste0("{",tolower(x),"}"), s, backref=0)
[1] "{cat}{cat}dog"

您可以使用gsubfn,就像在JavaScript 中使用String#replace 内部的匿名回调方法一样(您可以使用function(args) 指定捕获组的参数,并在内部进行更复杂的操作)。

【讨论】:

  • 能否请您解释一下上述示例中波浪号运算符的作用是什么?
  • 这是一个占位符,告诉gsubfn我们只需要使用里面的整个匹配文本(使用x访问),只需一个默认参数。
【解决方案2】:

您可以使用\\L 将匹配的大小写更改为小写

gsub(rx, "{\\L\\1}", x, perl=TRUE) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多