【问题标题】:Identifying substrings based on complex rules基于复杂规则识别子串
【发布时间】:2015-07-16 08:51:30
【问题描述】:

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

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

在这里我想识别标记序列(A 是一个标记,I3 是一个标记等)导致 到一个包含 个包含 I3IX 标记(即 I1I2I3)。该子序列的长度可以为 1(即为单个 I3 标记),也可以为无限长度,但始终需要包含至少 1 个 I3 标记,并且只能包含 IX 标记。在导致IX 子序列的子序列中,可以包括I1I2,但不能包括I3

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

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

导致I1-I3 子序列包含I3

D-D-D-D

导致I1-I1-I2-I1-I1-I3-I3 子序列至少包含1 个I3

这里有几个额外的例子:

A-B-I3-C-I3

从这个字符串我们应该识别A-B,因为它后面跟着一个包含I3的子序列1,还有C,因为它后面跟着一个包含I3的子序列1。

和:

I3-A-I3

这里应该识别A,因为它后面跟着一个包含I3的子序列1。第一个I3 本身不会被识别,因为我们只对后面跟着包含I3IX 标记子序列的子序列感兴趣。

如何编写一个通用函数/正则表达式来完成这项任务?

【问题讨论】:

  • 1.对于序列 A-B-I3-C-I3,答案应该是什么? [“A B”、“C”] 还是别的什么?
  • 2.对于序列 I3-A-I3,答案应该是什么?

标签: regex r string-matching


【解决方案1】:

使用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"

【讨论】:

  • 认为这是 op 所期望的......不是吗?
【解决方案2】:

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

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

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

查看演示https://regex101.com/r/bJ3iA3/4

【讨论】:

  • 我认为 \d 应该是 \\d,但我仍然无法让它在 R 中工作:invalid regular expression '(?:(?:I\d-?)*(?&lt;=I3)(?:-?I\d)*)', reason 'Invalid regexp'
  • @JakubP。是的,没有必要使用look behind。感谢您的关注!
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2017-08-05
    • 2011-01-16
    • 2012-05-13
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多