两个相关的问题。我有文本数据的向量,例如
"a(b)jk(p)" "ipq" "e(ijkl)"
并希望轻松地将其分成包含括号外文本的向量:
"ajk" "ipq" "e"
和一个包含括号内文本的向量:
"bp" "" "ijkl"
有什么简单的方法可以做到这一点?另一个困难是这些可能会变得很大并且有大量(无限)括号。因此,我不能简单地抓住括号中的文本“前/后”,需要一个更智能的解决方案。
括号外的文字
> x <- c("a(b)jk(p)" ,"ipq" , "e(ijkl)")
> gsub("\\([^()]*\\)", "", x)
[1] "ajk" "ipq" "e"
括号内的文字
> x <- c("a(b)jk(p)" ,"ipq" , "e(ijkl)")
> gsub("(?<=\\()[^()]*(?=\\))(*SKIP)(*F)|.", "", x, perl=T)
[1] "bp" "" "ijkl"
匹配括号内存在的(?<=\\()[^()]*(?=\\))
所有字符,然后以下内容(*SKIP)(*F)
使匹配失败。现在它尝试执行刚刚|
对剩余字符串进行符号化的模式。所以点.
匹配所有尚未跳过的字符。用空字符串替换所有匹配的字符将只给出球拍内的文本。
> gsub("\\(([^()]*)\\)|.", "\\1", x, perl=T)
[1] "bp" "" "ijkl"
此正则表达式将捕获括号内的所有字符并匹配所有其他字符。|.
or part 有助于匹配除捕获字符之外的所有剩余字符。因此,通过将所有字符替换为组索引 1 中存在的字符,将为您提供所需的输出。
我维护的qdapRegex包中的rm_round
函数就是为此而生的:
首先,我们将通过pacman获取并加载包
if (!require("pacman")) install.packages("pacman")
pacman::p_load(qdapRegex)
## 然后我们可以用它来删除和提取你想要的部分:
x <-c("a(b)jk(p)", "ipq", "e(ijkl)")
rm_round(x)
## [1] "ajk" "ipq" "e"
rm_round(x, extract=TRUE)
## [[1]]
## [1] "b" "p"
##
## [[2]]
## [1] NA
##
## [[3]]
## [1] "ijkl"
浓缩b
和p
使用:
sapply(rm_round(x, extract=TRUE), paste, collapse="")
## [1] "bp" "NA" "ijkl"