使用正则表达式拆分字符串

8

我希望你能帮我翻译一些与IT技术有关的内容。要翻译的内容是如何拆分一个通用格式的字符串,其中方括号表示字符串的“部分”。例如:

x <- "[a] + [bc] + 1"

并返回一个类似于字符向量的结果:
"[a]"  " + "  "[bc]" " + 1"

更新:最终使用以下方法:

x <- "[a] + [bc] + 1"
x <- gsub("\\[",",[",x)
x <- gsub("\\]","],",x)
strsplit(x,",")

请将您最终使用的答案发布为回答,而不是对帖子进行编辑。 - ggorlen
4个回答

6
我看过 TylerRinker 的代码,怀疑他的代码可能比这个更加清晰易懂,但是这个代码可以作为学习另一组函数的方式。(在我注意到它会在空格处分割字符串之前,我更喜欢 TylerRinker 的代码。)我尝试着将其改为使用 strsplit 函数,但是那个函数总是会删除分隔符。也许可以通过改动,制作一个新的 newstrsplit 函数,它可以在分隔符处进行分割,并保留它们。可能需要略过第一个或最后一个位置,并区分开头和结尾的分隔符。
scan(text=   # use scan to separate after insertion of commas
            gsub("\\]", "],",   # put commas in after "]"'s
            gsub(".\\[", ",[",  x)) ,  # add commas before "[" unless at first position
        what="", sep=",")    # tell scan this character argument and separators are ","
#Read 4 items
#[1] "[a]"  " +"   "[bc]" " + 1"

我喜欢这种方法,因为它不依赖于空格进行分割。在输出中保留空格对于此任务并不重要,因此我修改了它以使用strplit - Jeff Keller
感谢您的积极评论,但我认为@juba的回答更好。我将使用它来构建一个简单的解析函数,该函数接受一对参数来表示保留的开始和结束分隔符。 - IRTFM

5
这是一种懒惰的方法:
FUN <- function(x) {
    all <- unlist(strsplit(x, "\\s+"))
    last <- paste(c(" ", tail(all, 2)), collapse="")
    c(head(all, -2), last)
}

x <- "[a] + [bc] + 1"    
FUN(x)

## > FUN(x)
## [1] "[a]"  "+"    "[bc]" " +1"

你说“懒”,是因为你使用空格而不是括号来分隔吗? - IRTFM
是的(没有真正的强大的正则表达式) - Tyler Rinker

5
您可以手动计算分割点并使用 substring
split.pos <- gregexpr('\\[.*?]',x)[[1]]
split.length <- attr(split.pos, "match.length")
split.start <- sort(c(split.pos, split.pos+split.length))
split.end <- c(split.start[-1]-1, nchar(x))
substring(x,split.start,split.end)
#  [1] "[a]"  " + "  "[bc]" " + 1"

1
我们已经迈出了制作“newsplit”的重要一步。虽然我并不完全理解,但我认为gregexpr会很有用。我很惊讶你在模式中没有使用“\]”。 - IRTFM
我认为 ] 不需要转义,因为它不会被解释为字符类的结束,这是因为 [ 已经被解释了。嗯,不确定我表达得是否清楚 :-) - juba
我也有同样的想法,但它表明“特殊性”比我预期的更依赖于上下文。 - IRTFM

5

以下是使用正向和反向预查,按括号分割并将其保留在结果中的版本:

splitme <- function(x) {
  x <- unlist(strsplit(x, "(?=\\[)", perl=TRUE))
  x <- unlist(strsplit(x, "(?<=\\])", perl=TRUE))
  for (i in which(x=="[")) {
    x[i+1] <- paste(x[i], x[i+1], sep="")
  }
  x[-which(x=="[")]
}
splitme(x)
#[1] "[a]"  " + "  "[bc]" " + 1"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接