【问题标题】:Isolate alphabetical strings within a larger string在较大的字符串中隔离字母字符串
【发布时间】:2017-08-06 19:04:40
【问题描述】:

有没有办法隔离按字母顺序排列的字符串部分?

换句话说,如果你有这样的字符串:hjubcdepyvb

你能按字母顺序拉出那部分吗?:bcde

我曾考虑过使用is.unsorted() 函数,但我不确定如何仅将其应用于字符串的一部分。

【问题讨论】:

    标签: r string sorting alphabetical


    【解决方案1】:

    这是转换为 ASCII 并返回的一种方法:

    input <- "hjubcdepyvb"
    spl_asc <- as.integer(charToRaw(input))       # Convert to ASCII
    d1 <- diff(spl_asc) == 1                      # Find sequences
    filt <- spl_asc[c(FALSE, d1) | c(d1, FALSE)]  # Only keep sequences (incl start and end)
    rawToChar(as.raw(filt))                       # Convert back to character
    
    #[1] "bcde"
    

    请注意,这将连接按字母顺序排列的所有部分。

    即如果输入为"abcxasdicfgaqwe",则输出为abcfg

    如果您想为每个连续的字符串获取单独的向量,您可以执行以下操作

    input <- "abcxasdicfgaqwe"
    spl_asc <- as.integer(charToRaw(input))
    d1 <- diff(spl_asc) == 1
    r <- rle(c(FALSE, d1) | c(d1, FALSE))                   # Find boundaries
    cm <- cumsum(c(1, r$lengths))                           # Map these to string positions
    substring(input, cm[-length(cm)], cm[-1] - 1)[r$values] # Extract matching strings
    

    最后,我不得不想出一个使用正则表达式的方法:

    input <- c("abcxasdicfgaqwe", "xufasiuxaboqdasdij", "abcikmcapnoploDEFgnm",
               "acfhgik")
    (rg <- paste0("(", paste0(c(letters[-26], LETTERS[-26]),
                               "(?=", c(letters[-1], LETTERS[-1]), ")", collapse = "|"), ")+."))
    
    #[1] "(a(?=b)|b(?=c)|c(?=d)|d(?=e)|e(?=f)|f(?=g)|g(?=h)|h(?=i)|i(?=j)|j(?=k)|
    #k(?=l)|l(?=m)|m(?=n)|n(?=o)|o(?=p)|p(?=q)|q(?=r)|r(?=s)|s(?=t)|t(?=u)|u(?=v)|
    #v(?=w)|w(?=x)|x(?=y)|y(?=z)|A(?=B)|B(?=C)|C(?=D)|D(?=E)|E(?=F)|F(?=G)|G(?=H)|
    #H(?=I)|I(?=J)|J(?=K)|K(?=L)|L(?=M)|M(?=N)|N(?=O)|O(?=P)|P(?=Q)|Q(?=R)|R(?=S)|
    #S(?=T)|T(?=U)|U(?=V)|V(?=W)|W(?=X)|X(?=Y)|Y(?=Z))+."
    
    regmatches(input, gregexpr(rg, input, perl = TRUE))
    #[[1]]
    #[1] "abc" "fg" 
    #
    #[[2]]
    #[1] "ab" "ij"
    #
    #[[3]]
    #[1] "abc" "nop" "DEF"
    #
    #[[4]]
    #character(0)
    

    此正则表达式将识别连续的大写或小写字母(但不区分大小写)。正如所展示的,它适用于字符向量并生成一个向量列表,其中包含所有已识别的匹配项。如果未找到匹配项,则输出为character(0)

    【讨论】:

      【解决方案2】:

      使用因子整数转换:

      input <- "hjubcdepyvb"
      d1 <- diff(as.integer(factor(unlist(strsplit(input, "")), levels = letters))) == 1
      filt <- c(FALSE, d1) | c(d1, FALSE)
      paste(unlist(strsplit(input, ""))[filt], collapse = "")
      # [1] "bcde"
      

      【讨论】:

        【解决方案3】:
        myf = function(x){
            x = unlist(strsplit(x, ""))
            ind = charmatch(x, letters)
            d = c(0, diff(ind))
            d[d !=1] = 0
            d = d + c(sapply(1:(length(d)-1), function(i) {
                ifelse(d[i] == 0 & d[i+1] == 1, 1, 0)
            }
            ), 0)
            d = split(seq_along(d)[d!=0], with(rle(d), rep(seq_along(values), lengths))[d!=0])
            return(sapply(d, function(a) paste(x[a], collapse = "")))
        }
        
        myf(x = "hjubcdepyvblltpqrs")
        #     2      4 
        #"bcde" "pqrs" 
        

        【讨论】:

          猜你喜欢
          • 2012-02-17
          • 1970-01-01
          • 2014-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-02
          • 2014-12-04
          • 1970-01-01
          相关资源
          最近更新 更多