![](/img/trans.png)
[英]R/regex with stringi/ICU: why is a '+' considered a non-[:punct:] character?
[英]R: Regex madness (stringi)
我有一個向量像這樣的字符串:
G30(H).G3(M).G0(L).Replicate(1)
迭代c("H", "M", "L")
,我想提取G30
(對於“ H
”), G3
(對於“ M
”)和G0
(對於“ L
”)。
我的種種嘗試使我感到困惑regex101.com
調試器,例如表明(\\w*)\\(M\\)
正常,但是將其傳輸到R失敗...
使用stringi
包和outer()
函數:
library(stringi)
strings <- c(
"G30(H).G3(M).G0(L).Replicate(1)",
"G5(M).G11(L).G6(H).Replicate(9)",
"G10(M).G6(H).G8(M).Replicate(200)" # No "L", repeated "M"
)
targets <- c("H", "M", "L")
patterns <- paste0("\\w+(?=\\(", targets, "\\))")
matches <- outer(strings, patterns, FUN = stri_extract_first_regex)
colnames(matches) <- targets
matches
# H M L
# [1,] "G30" "G3" "G0"
# [2,] "G6" "G5" "G11"
# [3,] "G6" "G10" NA
這將忽略目標字母后面的任何實例,在找不到目標字母時為您提供NA
,並以簡單矩陣形式返回所有內容。 存儲在patterns
中的正則表達式匹配諸如XX(Y)
子字符串,其中Y
是目標字母,而XX
是任意數量的單詞字符。
我敢肯定,有更好的解決方案,但這行得通...
jnk <- 'G30(H).G3(M).G0(L).Replicate(1)'
patter <- '([^\\(]+)\\(H\\)\\.([^\\(]+)\\(M\\)\\.([^\\(]+)\\(L\\)\\.Replicate\\(\\d+\\)'
H <- sub(patter, '\\1', jnk)
M <- sub(patter, '\\2', jnk)
L <- sub(patter, '\\3', jnk)
編輯:
實際上,我曾經發現一個很好的函數parse.one
,它使得像正則表達式一樣可以在python中搜索更多...
看看這個:
parse.one <- function(res, result) {
m <- do.call(rbind, lapply(seq_along(res), function(i) {
if(result[i] == -1) return("")
st <- attr(result, "capture.start")[i, ]
substring(res[i], st, st + attr(result, "capture.length")[i, ] - 1)
}))
colnames(m) <- attr(result, "capture.names")
m
}
jnk <- 'G30(H).G3(M).G0(L).Replicate(1)'
pattern <- '(?<H>[^\\(]+)\\(H\\)\\.(?<M>[^\\(]+)\\(M\\)\\.(?<L>[^\\(]+)\\(L\\)\\.Replicate\\(\\d+\\)'
parse.one(jnk, regexpr(pattern, jnk, perl=TRUE))
結果如下:
> parse.one(jnk, regexpr(pattern, jnk, perl=TRUE))
H M L
[1,] "G30" "G3" "G0"
如果順序始終相同,則可以選擇拆分字符串。 例如:
string <- "G30(H).G3(M).G0(L).Replicate(1)"
tmp <- str_split(string, "\\.")[[1]]
lapply(tmp[1:3], function(x) str_split(x, "\\(")[[1]][1])
[[1]]
[1] "G30"
[[2]]
[1] "G3"
[[3]]
[1] "G0"
如果允許更改標簽(例如“(H)”)前面的代碼(例如“ G30”)或字符串中標簽的順序(不同的字母或長度),則可以嘗試使用更靈活的方法基於regexpr()的解決方案。
aa <-paste("G30(H).G3(M).G0(L).Replicate(",1:10,")", sep="")
my.tags <- c("H","M", "L")
extr.data <- lapply(my.tags, (function(tag){
pat <- paste("\\(", tag, "\\)\\.", sep="")
pos <- regexpr(paste("(^|\\.)([[:alnum:]])*", pat ,sep=""), aa)
out <- substr(aa, pos, (pos+attributes(pos)$match.length - 4 - length(tag)))
gsub("(^\\.)", "", out)
}))
names(extr.data) <- my.tags
extr.data
我將假設函數(G ...)是變量,輸入是變量。 這確實假設您的函數以G開頭,並且您的輸入始終為字母。
parse = function(arb){
tmp = stringi::stri_extract_all_regex(arb,"G.*?\\([A-Z]\\)")[[1]]
unlist(lapply(lapply(tmp,strsplit,"\\)|\\("),function(x){
output = x[[1]][1]
names(output) = x[[1]][2]
return(output)
}))
}
這首先解析所有G函數及其輸入。 然后,將它們分別分解為功能部分和輸入部分。 這是將以其輸入命名的函數放入一個字符向量中。
parse("G30(H).G3(M).G0(L).Replicate(1)")
> H M L
"G30" "G3" "G0"
要么
parse("G35(L).G31(P).G02(K).Replicate(1)")
> L P K
"G35" "G31" "G02"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.