jba*_*ums 9 regex string r substitution
给定一组正则表达式,是否有一种简单的方法来匹配多个模式,并根据匹配的模式替换匹配的文本?
例如,对于以下数据x,每个元素以数字或字母开头,并以数字或字母结尾.让我们称这些模式num_num(以数字开头,以数字结尾),num_let(以数字开头,以字母结尾)let_num,和let_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:]])$'
)
Run Code Online (Sandbox Code Playgroud)
要用它后面的模式名称替换每个字符串,我们可以这样做:
m <- lapply(type, grep, x)
rep(names(type), sapply(m, length))[order(unlist(m))]
## [1] "num_let" "num_let" "let_num" "num_num" "num_num" "let_let"
Run Code Online (Sandbox Code Playgroud)
有更有效的方法吗?
gsubfn?我知道gsubfn我们可以同时替换不同的比赛,例如:
library(gsubfn)
gsubfn('.*', list('1p33'='foo', '123abc'='bar'), x)
## [1] "bar" "78fdsaq" "aq12111" "foo" "123" "pzv"
Run Code Online (Sandbox Code Playgroud)
但我不确定替换是否可以依赖于匹配的模式而不是匹配本身.
stringr?str_replace_all不能很好地使用这个例子,因为迭代地将匹配替换为模式,我们最终会被覆盖的所有内容let_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"
Run Code Online (Sandbox Code Playgroud)
重新排序type所以对应的模式let_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"
Run Code Online (Sandbox Code Playgroud)
我们可以使用str_replace_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"
Run Code Online (Sandbox Code Playgroud)
另一种方法是先匹配然后替换,一种方法是使用greplandtidyr
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"
Run Code Online (Sandbox Code Playgroud)
虽然这种方法看起来效率不高,但它可以轻松查找多于或少于一个匹配项的行。
据我了解,替换匹配是在 pcre2 中实现的,我相信可以直接在正则表达式中解决此类问题。不幸的是,似乎还没有人为 R 构建 pcre2 包。
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |