Regex 根据匹配的模式替换匹配项

Regex 根据匹配的模式替换匹配项,regex,r,string,substitution,Regex,R,String,Substitution,给定一组正则表达式,是否有一种简单的方法来匹配多个模式,并根据匹配的模式替换匹配的文本 例如,对于以下数据x,每个元素以数字或字母开头,以数字或字母结尾。让我们将这些模式称为num\u num(for以数字开头,以数字结尾)、num\u Let(以数字开头,以字母结尾)、Let\u num和Let\u Let x <- c('123abc', '78fdsaq', 'aq12111', '1p33', '123', 'pzv') type <- list( num_let='^\

给定一组正则表达式,是否有一种简单的方法来匹配多个模式,并根据匹配的模式替换匹配的文本

例如,对于以下数据
x
,每个元素以数字或字母开头,以数字或字母结尾。让我们将这些模式称为
num\u num
(for以数字开头,以数字结尾)、
num\u Let
(以数字开头,以字母结尾)、
Let\u num
Let\u Let

x <- c('123abc', '78fdsaq', 'aq12111', '1p33', '123', 'pzv')
type <- list(
  num_let='^\\d.*[[:alpha:]]$',
  num_num='^\\d(.*\\d)?$',
  let_num='^[[:alpha:]].*\\d$',
  let_let='^[[:alpha:]](.*[[:alpha:]])$'
)
但我不确定是否可以根据匹配的模式而不是匹配本身进行替换


stringr
str\u replace\u all
不能很好地处理这个示例,因为模式的匹配项会被迭代地替换,最终所有内容都会被
let\u let
覆盖:

library(stringr)
str_replace_all(x, setNames(names(type), unlist(type)))
## [1] "let_let" "let_let" "let_let" "let_let" "let_let" "let_let"
重新排序
类型
,因此与
let\u let
对应的模式首先出现,解决了问题,但需要这样做让我感到紧张

type2 <- rev(type)
str_replace_all(x, setNames(names(type2), unlist(type2)))
## [1] "num_let" "num_let" "let_num" "num_num" "num_num" "let_let"
type2也许是其中之一

# base R method
mm2 <- character(length(x))
for( n in 1:length(type))  mm2 <- replace(mm2, grep(type[n],x), names(type)[n]) 

# purrr 0.2.0 method
library(purrr)
mm3 <- map(grep, .x=type, x = x) %>% (function(z) replace(x, flatten_int(z), rep(names(type), lengths(z))))
#基本R方法
mm2纵梁
如果我们更改替换,使它们不再与任何正则表达式匹配,然后添加一个额外的替换以将其返回到原始形式,则可以使用
str\u replace\u all
。比如说

library(stringr)
type2 <- setNames(c(str_replace(names(type), "(.*)", "__\\1__"), "\\1"), 
                  c(unlist(type), "^__(.*)__$"))
str_replace_all(x, type2)
## [1] "num_let" "num_let" "let_num" "num_num" "num_num" "let_let"
虽然这种方法看起来效率不高,但它可以很容易地找到多个或少个匹配的行



据我所知,替换匹配是在pcre2中实现的,我相信它允许在正则表达式中直接解决这类问题。不幸的是,似乎还没有人为R构建pcre2包。

这个问题背后的动机是什么?你是在寻找一种计算效率高的方法,一种依赖于单个函数调用的方法还是其他方法?@NGaffney-对于我的应用程序来说,计算效率并不重要-我不会将这个问题放大很多,只需要执行几次操作。我发布这个问题是因为我在过去几次遇到过这个问题,并且怀疑有一种方法可以解决这个问题(特别是使用,例如,
gsubfn
,这对我来说仍然有点神秘)。我主要是想看看解决这个问题的其他方法,并建立我的字符串操作库。我希望看到一种依赖于单一功能的方法。我喜欢你在
type2
末尾加上的替代品-非常聪明。
# base R method
mm2 <- character(length(x))
for( n in 1:length(type))  mm2 <- replace(mm2, grep(type[n],x), names(type)[n]) 

# purrr 0.2.0 method
library(purrr)
mm3 <- map(grep, .x=type, x = x) %>% (function(z) replace(x, flatten_int(z), rep(names(type), lengths(z))))
library(stringr)
type2 <- setNames(c(str_replace(names(type), "(.*)", "__\\1__"), "\\1"), 
                  c(unlist(type), "^__(.*)__$"))
str_replace_all(x, type2)
## [1] "num_let" "num_let" "let_num" "num_num" "num_num" "let_let"
library(plyr)
library(dplyr)
library(tidyr)

out <- data.frame(t(1*aaply(type, 1, grepl, x)))

out[out == 0] <- NA
out <- out %>% 
  mutate(id = 1:nrow(.)) %>%
  gather(name,value, -id, na.rm = T) %>%
  select(name)
as.character(out[,1])
## [1] "num_let" "num_let" "num_num" "num_num" "let_num" "let_let"