您好我想了解如何将PCRE REGEX转换为ICU REGEX,以便我可以使用R函数str_match_all(stringr包的一部分)。
@WiktorStribiżew能够生成REGEX PCRE解析,如这些REGEX101演示中所示:
https://regex101.com/r/m4UD0j/17
这解析捕获aa和bb组合(每个组合前面有任何长度的任何数字),然后是cc组(前面用数字代替),例如10aa5bb6bb3bb6aa999cc998cc997cc
因此将字符串视为两部分:
第一个是aa或bb组合的随机集合(例如,这可能只是aa,例如),前面有一个数字。
下半部分是一系列cc(例如,这可能只是一个cc),前面有一个数字。
重要的是,字符串的两个边都被捕获在一起,文本和数字都是专门捕获的。所以有效的捕获是,例如:
2aa2cc
323233aa21212bb4555cc
1aa2aa3aa4aa5aa6aa117cc8cc
1bb2bb3bb4bb5bb6bb117cc8cc
1aa2bb3bb4aa5bb6bba117cc8cc
1aa2bb3bb4aa5bb6bba117cc8ccXXXXXXXXXX1aa2bb3bb4aa5bb6bba117cc8cc
无效:
2aa *Only one side of the string is there*
1aa2bb3bb4aa *Only one side of the string is there*
99cc100cc *Only one side of the string is there*
此外,我想要一个单独的REGEX表达式,用于“cc”组在字符串中排在第一位的情况,例如999cc998cc997cc10aa5bb6bb3bb6aa。这在这里得到证明:https://regex101.com/r/m4UD0j/18
注意:文本模式aa,bb和cc实际上是较长字符串的缩写,因此应该这样对待。我提供了更短的版本,以避免一个更令人困惑的例子。
这两个演示显示了不同组合顺序的正则表达式。
现在我必须使用str_match_all在R中运行,遗憾的是它使用ICU正则表达式,而不是我们在REGEX101中测试的pcre正则表达式。
所以我有这个代码,它抛出了一个尚未实现的正则表达式使用功能。 (U_REGEX_UNIMPLEMENTED)错误:
#REGEX TEST#
library(stringr)
regex_text_1 <- "8aa9aa10bb1cc2cc3cc"
#reg_pattern_1 that worked in REGEX101 <- "(?:\G(?!^)(?(?=\d+(?:aa|bb))(?<!\dcc))|(?=(?:\d+(?:aa|bb))+(?:\d+cc)+))(\d+)(aa|bb|cc)"
reg_pattern_1 <- "(?:\\G(?!^)(?(?=\\d+(?:aa|bb))(?<!\\dcc))|(?=(?:\\d+(?:aa|bb))+(?:\\d+cc)+))(\\d+)(aa|bb|cc)"
regex_text_2 <- "1cc2cc3cc8aa9bb10bb"
#reg_pattern_2 that worked in REGEX101 <- "(?:\G(?!^)(?(?=\d+cc)(?<!\d(?:aa|bb)))|(?=(?:\d+cc)+(?:\d+(?:aa|bb))+))(\d+)(aa|bb|cc)"
reg_pattern_2 <- "(?:\\G(?!^)(?(?=\\d+cc)(?<!\\d(?:aa|bb)))|(?=(?:\\d+cc)+(?:\\d+(?:aa|bb))+))(\\d+)(aa|bb|cc)"
sm <- str_match_all(regex_text_1, reg_pattern_1)
sm.df <- as.data.frame(sm)
print(sm.df)
sm <- str_match_all(regex_text_2, reg_pattern_2)
sm.df <- as.data.frame(sm)
print(sm.df)
我实际上喜欢它输出这样的东西:
X1 X2 X3
1 8aa 8 aa
2 9aa 9 aa
3 10bb 10 bb
4 1cc 1 cc
5 2cc 2 cc
6 3cc 3 cc
和
X1 X2 X3
1 1cc 1 cc
2 2cc 2 cc
3 3cc 3 cc
4 8aa 8 aa
5 9aa 9 aa
6 10bb 10 bb
......就像我们在pcre中应用它一样。
我不是专家将代码从pcre转换为icu所以非常感谢一些帮助。非常感谢...
好的,所以这不会转换为ICU,但更好。它是STR_MATCH_ALL的Perl版本。它工作得很漂亮。
感谢无论谁建造它。它来自这里:
### Parse several occurances of pattern from each of several strings
### using (named) capturing regular expressions, returning a list of
### matrices (with column names).
str_match_all_perl <- function(string,pattern){
stopifnot(is.character(string))
stopifnot(is.character(pattern))
stopifnot(length(pattern)==1)
parsed <- gregexpr(pattern,string,perl=TRUE)
lapply(seq_along(parsed),function(i){
r <- parsed[[i]]
starts <- attr(r,"capture.start")
if(r[1]==-1)return(matrix(nrow=0,ncol=1+ncol(starts)))
names <- attr(r,"capture.names")
lengths <- attr(r,"capture.length")
full <- substring(string[i],r,r+attr(r,"match.length")-1)
subs <- substring(string[i],starts,starts+lengths-1)
m <- matrix(c(full,subs),ncol=length(names)+1)
colnames(m) <- c("",names)
m
})
}
data.frame(do.call(rbind,regmatches(a<-strsplit(regex_text_1,'(?<=[a-z])(?=[0-9])',perl = T)[[1]],regexec('(\\d)(\\D+)',a))))
X1 X2 X3
1 8aa 8 aa
2 9aa 9 aa
3 0bb 0 bb
4 1cc 1 cc
5 2cc 2 cc
6 3cc 3 cc
或者在很多步骤中:
a = strsplit(regex_text_1, '(?<=[a-z])(?=[0-9])', perl = TRUE)[[1]]
b = regmatches(a, regexec('(\\d)(\\D+)', a))
data.frame(do.call(rbind, b))
X1 X2 X3
1 8aa 8 aa
2 9aa 9 aa
3 0bb 0 bb
4 1cc 1 cc
5 2cc 2 cc
6 3cc 3 cc
你可以用regex_text_2
做同样的事情。如果有的话,你有很多:
ff = function(x)data.frame(do.call(rbind,regmatches(a<-strsplit(x,'(?<=[a-z])(?=[0-9])',perl = T)[[1]],regexec('(\\d)(\\D+)',a))))
ff(regex_text_1)
X1 X2 X3
1 8aa 8 aa
2 9aa 9 aa
3 0bb 0 bb
4 1cc 1 cc
5 2cc 2 cc
6 3cc 3 cc
ff(regex_text_2)
X1 X2 X3
1 1cc 1 cc
2 2cc 2 cc
3 3cc 3 cc
4 8aa 8 aa
5 9bb 9 bb
6 0bb 0 bb
你也可以使用gsub
做:
transform(read.table(text=gsub('(\\d+)(\\D+)','\\1 \\2\n',regex_text_1)),v3=paste0(V1,V2))
V1 V2 v3
1 8 aa 8aa
2 9 aa 9aa
3 10 bb 10bb
4 1 cc 1cc
5 2 cc 2cc
6 3 cc 3cc