根据复杂规则识别子字符串

时间:2015-07-16 08:51:30

标签: regex r string-matching

假设我的文字字符串看起来像这样:

A-B-C-I1-I2-D-E-F-I1-I3-D-D-D-D-I1-I1-I2-I1-I1-I3-I3

在这里,我想识别标记序列(A是标记,I3是标记等) 引导 到包含IX标记的 的子序列(即I1I2I3) {1}}。此子序列的长度可以为1(即单个I3标记),或者可以是无限长度,但始终需要包含至少1个I3标记,并且只能包含{{1标记。在导致I3子序列的子序列中,可以包含IXIX,但不能包含I1

在上面的字符串中,我需要识别:

I2

指向包含I3

A-B-C-I1-I2-D-E-F 子序列

I1-I3

指向包含至少1 I3的{​​{1}}子序列。

以下是一些其他示例:

D-D-D-D

从此字符串中我们应该标识I1-I1-I2-I1-I1-I3-I3,因为它后面跟着包含I3的1的子序列,还包含A-B-I3-C-I3 ,因为后面跟着包含1的子序列A-B

I3

此处C应该被识别,因为它后跟一个包含I3的子序列1。第一个I3-A-I3 本身将无法识别,因为我们只对包含A的{​​{1}}标记的子序列后面的子序列感兴趣。

如何编写完成此任务的通用函数/正则表达式?

3 个答案:

答案 0 :(得分:4)

使用strsplit

> x <- "A-B-C-I1-I2-D-E-F-I1-I3-D-D-D-D-I1-I1-I2-I1-I1-I3-I3"
> strsplit(x, "(?:-?I\\d+)*-?\\bI3-?(?:I\\d+-?)*")
[[1]]
[1] "A-B-C-I1-I2-D-E-F" "D-D-D-D"

> strsplit("A-B-I3-C-I3", "(?:-?I\\d+)*-?\\bI3\\b-?(?:I\\d+-?)*")
[[1]]
[1] "A-B" "C" 

> strsplit("A-B-I3-C-I3", "(?:-?I\\d+)*-?\\bI3\\b-?(?:I3-?)*")
[[1]]
[1] "A-B" "C"

答案 1 :(得分:1)

您可以使用以下正则表达式识别包含I3的序列:

(?:I\\d-?)*I3(?:-?I\\d)*

因此,您可以使用此正则表达式拆分文本以获得所需的结果。

请参阅演示https://regex101.com/r/bJ3iA3/4

答案 2 :(得分:0)

请尝试以下表达式:(.*?)(?:I[0-9]-)*I3(?:-I[0-9])*。 查看匹配组: https://regex101.com/r/yA6aV9/1