R 在知道某些子字符串的情况下拆分字符串
假设我有以下字符串和子字符串向量:R 在知道某些子字符串的情况下拆分字符串,r,regex,R,Regex,假设我有以下字符串和子字符串向量: x <- "abc[[+de.f[-[[g" v <- c("+", "-", "[", "[[") 获取匹配项的一个选项可能是: [a-z.]+匹配1+乘以a-z或点 |或 \[+匹配1+次[ |`或 [+-]匹配+或- | 例如,要获取匹配项,请执行以下操作: library(stringr) x <- "abc[[+de.f[-[[g" str_extract_all(x, "[a-z.]+|\\[+|[+-]") 库(stri
x <- "abc[[+de.f[-[[g"
v <- c("+", "-", "[", "[[")
获取匹配项的一个选项可能是:
匹配1+乘以a-z或点[a-z.]+
或|
匹配1+次\[+
[
- |`或
匹配[+-]
或+
-
library(stringr)
x <- "abc[[+de.f[-[[g"
str_extract_all(x, "[a-z.]+|\\[+|[+-]")
库(stringr)
使用stringr::str\u match\u all
和Hmisc::escapeRegex
:
x这似乎更像是一个词法分析问题,而不是匹配问题。我似乎用
library(minilexer)#devtools::install_github(“coolbutuntible/minilexer”)
模式基于纯正则表达式的解决方案
x <- "abc[[+de.f[-[[g"
v <- c("+", "-", "[", "[[")
## Escaping function
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
## Sorting by length in the descending order function
sort.by.length.desc <- function (v) v[order( -nchar(v)) ]
pat <- paste(regex.escape(sort.by.length.desc(v)), collapse="|")
pat <- paste0("(?s)", pat, "|(?:(?!", pat, ").)+")
res <- regmatches(x, gregexpr(pat, x, perl=TRUE))
## => [[1]]
## [1] "abc" "[[" "+" "de.f" "[" "-" "[[" "g"
请参见regex演示和Regulex图表:
详细信息
(?s)
-使
匹配任何字符(包括换行符)的点调用修饰符
\[\[
-[[
子字符串(使用regex.escape转义)
|
-或
\+
-a+
|-
-或-
(无需转义-
,因为它不在字符类中)
\[
-或[
|
-或
(?:(?!\[\[\+\\+-\[)+
-匹配任何字符(
)的一种,尽可能多地重复1次或更多次(+
,在结尾),这不会开始一个[
,+
,-
或[
字符序列(了解更多信息)
<>你也可以考虑一个较少的“正则表达式密集型”的解决方案:
x <- "abc[[+de.f[-[[g"
v <- c("+", "-", "[", "[[")
## Escaping function
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
## Sorting by length in the descending order function
sort.by.length.desc <- function (v) v[order( -nchar(v)) ]
## Interleaving function
riffle3 <- function(a, b) {
mlab <- min(length(a), length(b))
seqmlab <- seq(length=mlab)
c(rbind(a[seqmlab], b[seqmlab]), a[-seqmlab], b[-seqmlab])
}
pat <- paste(regex.escape(sort.by.length.desc(v)), collapse="|")
res <- riffle3(regmatches(x, gregexpr(pat, x), invert=TRUE)[[1]], regmatches(x, gregexpr(pat, x))[[1]])
res <- res[res != ""]
## => [1] "abc" "[[" "+" "de.f" "[" "-" "[[" "g"
x谢谢,这可能是正确的选择,但你对我的数据做出了强有力的假设,字符可能是anything@Moody_Mudskipper它基于示例中的字符串。您可以使用希望允许的字符扩展character类。您创建了[+
进入一个异常,然后手动编码+
和-
,以一种只对单个字符有效的方式,我需要从向量变量开始,使用lappy对每个字符进行转义(tmp,function(x)paste0(\\”,x,collapse=”“)
?这充满了问题。使用Hmisc::escapeRegex
使它更干净,它的代码与您的regex类似。escape
Myregex。在我看来,escape
是最好的,因为它只会转义那些可能需要转义的字符。不过,我不包括空格和
,因为很少使用自由间距模式使用R正则表达式。这几乎是完美的:temp@Moody\u Mudskipper如果你查看lex()
的源代码,它基本上也在做str\u match\u all()
答案中的方法。可能有更好的方法来构建一个合适的快速词法分析器,但这类东西在C级通常更容易。坚持你的答案可能会更容易。谢谢,这就是我使用的方法。我也喜欢这是100%的基R。虽然我没有做基准测试,但事后看来,速度并不是一个真正的问题问题。@Moody_Mudskipper注意到,一个贪婪的令牌会消耗资源,而且速度可能会很慢。但是,这是纯正则表达式的唯一方法,因为您的数据是动态的。如果您事先知道v
内容,您可以手动优化该模式,但它是用户定义的,没有优化的方法。
library(stringr)
x <- "abc[[+de.f[-[[g"
str_extract_all(x, "[a-z.]+|\\[+|[+-]")
library(minilexer) #devtools::install_github("coolbutuseless/minilexer")
patterns <- c(
dbracket = "\\[\\[",
bracket = "\\[",
plus = "\\+",
minus = "\\-",
name = "[a-z.]+"
)
x <- "abc[[+de.f[-[[g"
lex(x, patterns)
unname(lex(x, patterns))
# [1] "abc" "[[" "+" "de.f" "[" "-"
# [7] "[[" "g"
x <- "abc[[+de.f[-[[g"
v <- c("+", "-", "[", "[[")
## Escaping function
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
## Sorting by length in the descending order function
sort.by.length.desc <- function (v) v[order( -nchar(v)) ]
pat <- paste(regex.escape(sort.by.length.desc(v)), collapse="|")
pat <- paste0("(?s)", pat, "|(?:(?!", pat, ").)+")
res <- regmatches(x, gregexpr(pat, x, perl=TRUE))
## => [[1]]
## [1] "abc" "[[" "+" "de.f" "[" "-" "[[" "g"
(?s)\[\[|\+|-|\[|(?:(?!\[\[|\+|-|\[).)+
x <- "abc[[+de.f[-[[g"
v <- c("+", "-", "[", "[[")
## Escaping function
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
## Sorting by length in the descending order function
sort.by.length.desc <- function (v) v[order( -nchar(v)) ]
## Interleaving function
riffle3 <- function(a, b) {
mlab <- min(length(a), length(b))
seqmlab <- seq(length=mlab)
c(rbind(a[seqmlab], b[seqmlab]), a[-seqmlab], b[-seqmlab])
}
pat <- paste(regex.escape(sort.by.length.desc(v)), collapse="|")
res <- riffle3(regmatches(x, gregexpr(pat, x), invert=TRUE)[[1]], regmatches(x, gregexpr(pat, x))[[1]])
res <- res[res != ""]
## => [1] "abc" "[[" "+" "de.f" "[" "-" "[[" "g"