【问题标题】:Combining regex with a literal string将正则表达式与文字字符串相结合
【发布时间】:2015-08-03 13:33:42
【问题描述】:

我有以下代码:

input <- "1-FA-1-I2-1-I2-1-I2-1-EX-1-I2-1-I3-1-FA-1-I1-1-I2-1-TR-1-I1-1-I2-1-FA-1-I3-1-I1-1-FA-1-FA-1-NR-1-I3-1-I2-1-TR-1-I1-1-I2-1-I1-1-I2-1-FA-1-I2-1-I1-1-I3-1-FA-1-QU-1-I1-1-I2-1-I2-1-I2-1-NR-1-I2-1-I2-1-NR-1-I1-1-I2-1-I1-1-NR-1-I3-1-QU-1-I2-1-I3-1-QU-1-NR-1-I2-1-I1-1-NR-1-QU-1-QU-1-I2-1-I1-1-EX"

innovation_patterns <- gsub(input, pattern = "-1-", replacement = "-")
innovation_patterns <- lapply(innovation_patterns, str_extract_all, '(?:I\\d-?)*I3(?:-?I\\d)*')

这个输出:

"I2-I3"    "I3-I1"    "I3-I2"    "I2-I1-I3" "I3"       "I2-I3" 

但是,我只想提取紧跟特定字符串的正则表达式的匹配项,例如:

仅当正则表达式前面有文字字符串时才匹配它 FA-I2-I2-I2-EX

例如,这将是正则表达式的第一个匹配项,而第二个匹配项前面是 FA-I1-I2-TR-I1-I2-FA

预期的输出与上面的正则表达式大致相同,但只选择了 5 个匹配项中的一个,因为它需要以特定的文字字符串开头。

如何修改这个正则表达式来达到这个目的?我假设它需要使用积极的后视来首先识别文字字符串,然后执行正则表达式。

【问题讨论】:

  • 你的预期输出是什么?
  • 但是没有子字符串FA-I2-I2-I2-EX
  • @AvinashRaj:一旦你这样做了innovation_patterns &lt;- gsub(input, pattern = "-1-", replacement = "-"),就会有。

标签: regex r


【解决方案1】:

我不知道我是否完全理解你的意思,但似乎你可以使用positive lookbehind

例如:

(?&lt;=a)b(正向后视)匹配cab 中的b(且仅b),但不匹配beddebt

【讨论】:

  • 是的,它需要积极的向后看,questin 是如何实现它。
  • the second answer here 可能有用。
  • 是的,或者 mpiktas 的第三个更好
【解决方案2】:

应该有更直观的东西,但我认为这可以完成工作

literal <- "FA-I2-I2-I2-EX"
innovation_patterns <- gsub(input, pattern = "-1-", replacement = "-")
a <- lapply(strsplit(innovation_patterns, literal )[[1]], str_extract_all, '(?:I\\d-?)*I3(?:-?I\\d)*')
b <- lapply(2:length(a), function(x){
           a[[x]][[1]][1]
     })

print(b)

【讨论】:

    【解决方案3】:

    使用(*SKIP)(*F)

    innovation_patterns <- gsub(input, pattern = "-1-", replacement = "-")
    innovation_patterns <- lapply(innovation_patterns, str_extract_all, perl('FA-I1-I2-TR-I1-I2-FA.*(*SKIP)(*F)|(?:I\\d-?)*I3(?:-?I\\d)*'))
    

    语法是这样的,

     partIDontWant.*(*SKIP)(*F)|choose from the string which exists before partIDontWant
    

    DEMO

    【讨论】:

    • 我无法让它在 R 中工作:Error in stri_extract_all_regex(string, pattern, simplify = simplify, : Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX)
    • 认为是perl('FA-I1-I2-TR-I1-I2-FA.*(*SKIP)(*F)|(?:I\\d-?)*I3(?:-?I\\d)*')
    • 我认为(*SKIP)(*F)stri_extract_all 存在一些问题(str_extract 正在使用stringi 库)。 perl(... 仍然给我错误。
    【解决方案4】:

    这是您可以解决此问题的另一种方法。

    x <- "1-FA-1-I2-1-I2-1-I2-1-EX-1-I2-1-I3-1-FA-1-I1-1-I2-1-TR-1-I1-1-I2-1-FA-1-I3-1-I1-1-FA-1-FA-1-NR-1-I3-1-I2-1-TR-1-I1-1-I2-1-I1-1-I2-1-FA-1-I2-1-I1-1-I3-1-FA-1-QU-1-I1-1-I2-1-I2-1-I2-1-NR-1-I2-1-I2-1-NR-1-I1-1-I2-1-I1-1-NR-1-I3-1-QU-1-I2-1-I3-1-QU-1-NR-1-I2-1-I1-1-NR-1-QU-1-QU-1-I2-1-I1-1-EX"
    

    代码

    substr <- 'FA-I2-I2-I2-EX'
    regex <- paste0(substr, '-?((?:I\\d-?)*I3(?:-?I\\d)*)')
    gsubfn::strapply(gsub('-1-', '-', x), regex, simplify = c)
    ## [1] "I2-I3"
    

    【讨论】:

      【解决方案5】:

      实现方法如下:

      lapply(innovation_patterns, str_extract_all, '(?<=FA-I2-I2-I2-EX-?)(?:I\\d-?)*I3(?:-?I\\d)*');
      ## [[1]]
      ## [[1]][[1]]
      ## [1] "I2-I3"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-30
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 2015-07-13
        • 2015-08-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多