代码之家  ›  专栏  ›  技术社区  ›  Dmitry D. Onishchenko

根据条件替换字符串中的匹配模式

  •  0
  • Dmitry D. Onishchenko  · 技术社区  · 6 年前

    我有一个包含数字、字母和空格的文本字符串。它的一些子字符串是月份缩写。我想执行一个基于条件的模式替换,即用空格括起一个月的缩写 如果且仅当 满足给定条件。例如,条件如下:“前面有数字,后面有字母”。

    stringr 包,但我无法组合函数 str_replace_all() str_locate_all() :

    # Input:
    txt = "START1SEP2 1DECX JANEND"
    # Desired output:
    # "START1SEP2 1 DEC X JANEND"
    
    # (A) What I could do without checking the condition:
    library(stringr)
    patt_month = paste("(", paste(toupper(month.abb), collapse = "|"), ")", sep='')
    str_replace_all(string = txt, pattern = patt_month, replacement = " \\1 ")
    # "START1 SEP 2 1 DEC X  JAN END"
    
    # (B) But I actually only need replacements inside the condition-based bounds:
    str_locate_all(string = txt, pattern = paste("[0-9]", patt_month, "[A-Z]", sep=''))[[1]]
    #      start end
    # [1,]    12  16
    
    # To combine (A) and (B), I'm currently using an ugly for() loop not shown here and want to get rid of it
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   Jan    6 年前

    您正在寻找环顾:

    (?<=\d)DEC(?=[A-Z])
    

    a demo on regex101.com


    Lookarounds确保在不使用任何字符的情况下匹配某个位置。它们在某物(称为lookbehind)前面可用,或者确保后面的任何东西是某种类型(称为lookahead)。正反两面都有,所以有四种类型(正/负)。向后看/向前看)。

    简短的备忘录:
    • (?=...)
    • (?!...) 是阴性。展望未来
    • (?<=...) 是一个pos.lookbehind
    • (?<!...) 是阴性。回头看
        2
  •  0
  •   GWD    6 年前

    基本R版本

    patt_month <- capture.output(cat(toupper(month.abb),"|"))#concatenate all month.abb with OR  
    pat <- paste0("(\\s\\d)(", patt_month, ")([A-Z]\\s)")#make it a three group thing 
    gsub(pattern = pat, replacement = "\\1 \\2 \\3", txt, perl =TRUE)#same result as above
    

    也适用于 txt2 <- "START1SEP2 1JANY JANEND" 开箱即用。

    [1] "START1SEP2 1 JAN Y JANEND"
    
    推荐文章