代码之家  ›  专栏  ›  技术社区  ›  Dre

如何在不知道R中单词的情况下匹配某个字符后的单词?

  •  1
  • Dre  · 技术社区  · 8 年前

    我想在a后面匹配这个词 - 在我的课文中,如果匹配的单词是另一个单词的结尾,那么我想在单词和匹配的单词之间进行拆分。

    文本示例:

    JOHN LION - XYZ RAN RUN TREEABC GRASS - ABC LIMB RAN RUN LION -XYZ JOG SUN
    SKY - ABC LION JOHN PONDABC RUN - PDF STONE
    

    我希望文本看起来像什么:

    JOHN LION - XYZ RAN RUN TREE ABC GRASS - ABC LIMB RAN RUN LION -XYZ JOG SUN
    SKY - ABC LION JOHN POND ABC RUN - PDF STONE
    

    我不想做 grepl gsub 在…上 ABC 因为破折号后面的单词总是在变化,并且会多次出现。同样,位于匹配单词前面的单词也将总是不同的,并且不会总是不同的 TREE 。不管匹配的单词前面是什么单词,我总是想进行拆分。

    如果我执行以下str_extract:

    str_extract(df, "(?<=-\\s)\\w+")
    

    然后我匹配 XYZ 基础知识 .

    我只想在 - 如果它也在另一个单词的末尾,但我也不知道另一个词会是什么。

    我不知所措。如果需要更多信息,请告诉我。任何帮助都将不胜感激。

    1 回复  |  直到 8 年前
        1
  •  3
  •   alistaire    8 年前

    这里有一个温和的方法。让我们调用数据 s :

    s <- 'JOHN LION - XYZ RAN RUN TREEABC GRASS - ABC LIMB RAN RUN LION -XYZ JOG SUN SKY - ABC LION JOHN PONDABC RUN - PDF STONE'
    

    具有 stringr ,让我们使用现有的正则表达式来提取要匹配的模式:

    library(stringr)
    pat <- str_extract_all(s, "(?<=-\\s)\\w+")
    

    使用这些模式查找模式前有非空白字符且后面有空格的所有单词(即需要空格的单词):

    words <- str_extract_all(s, paste0('[A-Za-z0-9]+', pat[[1]], '\\s'))
    

    通过将模式替换为空格,然后替换为模式,在这些单词中插入空格。要同时完成这一切,您需要使用 lapply str_extract_all 生成列表。

    words2 <- lapply(1:length(words), function(x){           # a little hacky
      str_replace_all(words[[x]], pat[[1]][x], paste0(' ', pat[[1]][x]))
    })
    

    要用固定单词替换所有匹配的单词,我们需要运行 str_replace_all 每个单词和替换,所以我们要么需要更新 s 当我们用 sapply :

    sapply(1:length(words), function(x){                               # hacky
      s <<- str_replace_all(s, unlist(words)[x], unlist(words2)[x])    # hackier
    })
    

    这将产生一些无用的输出,但会更新 s ,或使用 for 循环,这有点干净:

    for(x in 1:length(words)){
      s <- str_replace_all(s, unlist(words)[x], unlist(words2)[x])
    }
    

    不管怎样,我们都会

    > s
    [1] "JOHN LION - XYZ RAN RUN TREE ABC GRASS - ABC LIMB RAN RUN LION -XYZ JOG SUN SKY - ABC LION JOHN POND ABC RUN - PDF STONE"