5

我有一个如下所示的字符串:

x <- "01(01)121210(01)0001"

我想将其拆分为一个向量,以便得到以下信息:

[1] "0" "1" "(01)" "1" "2" "1" "2" "1" "0" "(01)" "0" "0" "0" "1"

(|) 可以是 [|] 或 {|},括号之间的位数可以是 2 或更多。

我一直试图通过先在括号上分开来做到这一点:

unlist(strsplit(x, "(?<=[\\]\\)\\}])", perl=T))
[1] "01(01)" "121210(01)" "0001"

or unlist(strsplit(x, "(?<=[\\[\\(\\{])", perl=T))
[1] "01(" "01)121210(" "01)0001"

但我找不到将两者结合在一起的方法。然后,我希望拆分不包含括号的元素。

如果有人可以帮助我解决这个问题或者知道更优雅的方式来做到这一点,我将不胜感激。

非常感谢!

4

4 回答 4

4

只需将 PERL 选项更改为 TRUE 并根据以下模式拆分输入字符串。

(?<!\(|^)(?!\)|\d\)|$)

演示

R 正则表达式将是,

"(?<!\\(|^)(?!\\)|\\d\\)|$)"
于 2014-08-06T12:25:53.717 回答
3

这是另一种方式:

unlist(strsplit(x, '\\([^)]*\\)(*SKIP)(*F)|(?=)', perl=T))
# [1] "0"    "1"    "(01)" "1"    "2"    "1"    "2"    "1"    "0"    "(01)" "0"    "0"    "0"    "1" 

\\([^)]*\\)匹配括号中的任何内容,并(*SKIP)(*F)告诉正则表达式引擎在此模式上失败,如果它在字符串中找到该模式,则不要使用|. 另一侧的模式|(?=),这匹配字符之间的空格。

于 2014-08-06T12:44:10.737 回答
1

这可以在没有使用strapplygsubfn 包中的零宽度向前/向后表达式的情况下完成。正则表达式匹配一个数字或一个 ( 直到下一个 )。

library(gsubfn)

strapply(x, "\\d|\\(.*?\\)", c, perl = TRUE)[[1]]

给予:

 [1] "0"    "1"    "(01)" "1"    "2"    "1"    "2"    "1"    "0"    "(01)"
[11] "0"    "0"    "0"    "1"  

注意:在问题中显示的示例中, (...) 中的部分始终为两位数。如果总是这样,它可以进一步简化为:

strapplyc(x, "\\d|\\(...")[[1]]

更新添加注释。

于 2014-08-06T12:38:51.883 回答
1

另一种可能的方式:

unlist(strsplit(x, '(?!\\(?\\d*\\))', perl=T))

比 Matthew Plourde 方式更短但效率更低

或者像 G. Grothendieck 这样写道:

m<-gregexpr("\\d|\\([^)]*\\)", x)
regmatches(x, m)
于 2014-08-06T13:00:07.383 回答