【问题标题】:R - Split by "\n" or three spaces and retain at least one space when there are three spacesR - 用“\n”或三个空格分割,当有三个空格时至少保留一个空格
【发布时间】:2016-03-29 22:58:02
【问题描述】:

我希望我能解释一下,这样对你来说很容易。我需要这个,因为字符串中缺少的信息被标记为三个空格,而且令人惊讶的是,下一条信息没有执行\n

想象一下我有一个类似的字符串:

string <- "abc
   def
ghi   jkl"

我希望正则表达式(可能带有更高级功能的strsplit())的输出为:

[[1]]
[1] "abc" "" "def" "ghi" "" "jkl"

当它找到\n 时会拆分,当它找到三个空格时会拆分并插入一个空格。我需要将丢失的信息标记为另一个值。如果不是,那会破坏我的脚本,认为下一个信息是,例如,三个空格与def 字符串连接。

谢谢

【问题讨论】:

    标签: regex r split


    【解决方案1】:

    这里有两种解决方案,它们都使用strsplit,但它们的拆分方式不同:

    1) 在换行符处拆分 删除所有给出s1 的换行符,然后在给出s2 的每三个字符后添加一个换行符。在换行符上拆分 s2 并将每次出现的三个连续空格替换为空字符串。

    Split <- function(string) {
      s1 <- gsub("\n", "", string)
      s2 <- gsub("(.{3})", "\\1\n", s1)
      spl <- strsplit(s2, "\n")
      lapply(spl, function(s) replace(s, s == "   ", ""))
    }
    
    # test
    string <- "abc\n   def\nghi   jkl"
    Split(string)
    ## [[1]]
    ## [1] "abc" ""    "def" "ghi" ""    "jkl"
    

    2) 在零宽度上拆分 3 char regexp 删除换行符并使用指定的正则表达式拆分。最后将每连续三个空格替换为空字符串。

    Split2 <- function(string) {
      s1 <- gsub("\n", "", string)
      spl <- strsplit(s1, "(?<=...)", perl = TRUE)
      lapply(spl, function(s) replace(s, s == "   ", ""))
    }
    
    # test
    string <- "abc\n   def\nghi   jkl"
    Split2(string)
    ## [[1]]
    ## [1] "abc" ""    "def" "ghi" ""    "jkl"
    

    注意:1。请注意,提供给此问题的其他答案不适用于以下输入字符串(连续两个空字段),但此处的答案确实正确识别了 abc 字段之后连续两个空的 3 个字符字段:

    string2 <- "abc\n      def\nghi   jkl" # 6 spaces before d, 3 spaces before j
    
    Split(string2)
    ## [[1]]
    ## [1] "abc" ""    ""    "def" "ghi" ""    "jkl"
    
    Split2(string2)
    ## [[1]]
    ## [1] "abc" ""    ""    "def" "ghi" ""    "jkl"
    

    注意 2: 上面的两个解决方案也可以使用 magrittr 管道很好地表达:

    library(magrittr)
    string %>% 
      gsub(pattern = "\n", replacement = "") %>%
      gsub(pattern = "(.{3})", replacement = "\\1\n") %>%
      strsplit("\n") %>%
      lapply(function(s) replace(s, s == "   ", ""))
    
    ## [[1]]
    ## [1] "abc" ""    "def" "ghi" ""    "jkl"
    
    
    library(magrittr)
    string %>% 
      gsub(pattern = "\n", replacement = "") %>%
      strsplit("(?<=...)", perl = TRUE) %>%
      lapply(function(s) replace(s, s == "   ", ""))
    
    ## [[1]]
    ## [1] "abc" ""    "def" "ghi" ""    "jkl"
    

    【讨论】:

      【解决方案2】:
      (string <- "abc
         def
      ghi   jkl")
      # [1] "abc\n   def\nghi   jkl"
      
      rle(strsplit(string, '\\s')[[1]])$values
      # [1] "abc" ""    "def" "ghi" ""    "jkl"
      

      【讨论】:

        【解决方案3】:

        由于“”(3个空格)可以一个接一个出现, 使用正则表达式会很困难。

        如果“\n”可以被识别为单词分隔符 我的解决方案是首先将“”替换为“\n”,这没什么+单词分隔符 并照常进行strsplit。这是我的解决方案

        string <- "abc
           def
        ghi   jkl"
        string <- "abc\n      def\nghi   jkl" 
        str2 <- stri_replace_all_fixed(string, "   ", "\n")
        str3 <- stri_split_regex(str2, "\n")
        str3
        

        这两个例子的作用就像一个魅力

        【讨论】:

          猜你喜欢
          • 2019-11-29
          • 1970-01-01
          • 1970-01-01
          • 2021-03-10
          • 2015-07-18
          • 1970-01-01
          • 2012-10-03
          • 1970-01-01
          相关资源
          最近更新 更多