regex - 在 R 中的字符串中插入字符

标签 regex r

我想在字母(大写和小写)之间插入“&”,而不是在字母之前或之后,并替换每个小写字母 x来自 tt$X==0 , 每个大写字母 X来自 tt$X==1 , 和每个 +来自 )|( , 在整个字符串周围加上一个左括号和一个右括号,以获得可以在 R 中计算的表达式。 例如,我有字符串

st <- "AbC + de + FGHIJ"

结果应该如下所示:
"(tt$A==1 & tt$B==0 & tt$C==1) | (tt$D==0 & tt$E==0) | (tt$F==1 & tt$G==1 & tt$H==1 & tt$I==1 & tt$J==1)"

我可以用 gsub() 轻松做到这一点吗?功能?

最佳答案

你可以这样做,但它不是很优雅

st <- "AbC + de + FGHIJ"
t1 <- gsub("([a-z])", "tt\\$\\U\\1==0", st, perl = TRUE)
t2 <- gsub("((?<!\\$)[A-Z])", "tt\\$\\U\\1==1", t1, perl = TRUE)
t3 <- gsub("([0-9])(tt)", "\\1 & \\2", t2)
t4 <- gsub(" + ", ") | (", t3, fixed = TRUE)
t5 <- paste("(", t4, ")", sep = "")

st
# "AbC + de + FGHIJ"
t5
# "(tt$A==1 & tt$B==0 & tt$C==1) | (tt$D==0 & tt$E==0) | (tt$F==1 & tt$G==1 & tt$H==1 & tt$I==1 & tt$J==1)"

下面是它的作用的解释:

t1 用 tt$X==0 替换所有小写字母哪里X是被替换的大写字母。大写字母由 \\U\\1 产生哪里\\U生成大写和 \\1返回第一个捕获组。捕获组是在括号内捕获的内容。

既然小写字母已经不碍事(必须先做这样我们就不会替换 tt ),我们替换大写字母,但前提是它们前面有 $ .告诉gsub为了忽略美元符号后的大写字母,我们使用负回顾 (?<!)\\$告诉它忽略美元符号。然后我们再次用我们要替换的大写字母替换我们的字母。

接下来,我们需要在我们替换的所有字母之间插入一个空格。最好的方法就是承认 tt$每次需要空格时,前面都会有一个数字。因此,我们查找后跟“tt”的数字并将其替换为第一个捕获组“&”,然后是第二个捕获组。

然后我们需要替换“+”符号。所以我们用 ") | ("替换它和它周围的空格。我们使用 fixed = TRUE 来避免需要转义括号和 OR 运算符。

最后,我们附加前导和尾随括号,为我们提供一个功能齐全的条件短语。

编辑

根据其他解决方案中的评论,我们可以对我提出的解决方案进行一些更改,以 a) 使其更健壮,b) 更灵活。为了使它更健壮,我们只需更改 t4所以现在是:
t4 <- gsub(" ?\\+ ?", ") | (", t3)
我们简单地在空格后添加问号表示可以有 0 或 1,转义 + ,并删除 fixed = TRUE .我们必须删除 fixed = TRUE因为我们需要正则表达式函数来测试是否有空格。

为了使它更灵活,我们简单地将它包装在一个允许我们传递字符串和我们想要的对象名称的函数中。
parse_string <- function(string, object_name) {
  st <- string
  t1 <- gsub("([a-z])", paste0(object_name, "\\$\\U\\1==0"), st, perl = TRUE)
  t2 <- gsub("((?<!\\$)[A-Z])", paste0(object_name, "\\$\\U\\1==1"), t1, perl = TRUE)
  t3 <- gsub(paste0("([0-9])(", object_name, ")"), "\\1 & \\2", t2)
  t4 <- gsub(" ?\\+ ?", ") | (", t3)
  t5 <- paste("(", t4, ")", sep = "")
  return(t5)
}

> parse_string(st, "tt") == t5
# [1] TRUE
> parse_string(st, "foo")
# [1] "(foo$A==1 & foo$B==0 & foo$C==1) | (foo$D==0 & foo$E==0) | (foo$F==1 & foo$G==1 & foo$H==1 & foo$I==1 & foo$J==1)"
> parse_string("AbC+de+FGHIJ", "tt") == t5
# [1] TRUE

关于regex - 在 R 中的字符串中插入字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34620215/

相关文章:

regex - 正则表达式: '\<' vs'\b'

r - 在 R 中对数据行或列进行分组

r - 如何将Rtools\bin添加到R中的系统路径

r - 用 R 求解欠定线性系统

从互联网读取数据

R DOLS(动态普通最小二乘法)包

regex - 在 perl 中搜索和用普通破折号替换小数破折号的正则表达式?

javascript - 这个 JavaScript 正则表达式有什么作用

regex - 为什么我的替代品中的 $1 是空的?

java - 不以单词开头、不包含另一个单词但以第三个单词结尾的字符串的正则表达式