如何匹配某个字符后的单词而不知道R中的单词?

时间:2016-02-05 03:58:15

标签: regex r gsub stringr grepl

我想在我的文本中-之后匹配单词然后如果匹配的单词是另一个单词的结尾,那么我想在单词和匹配的单词之间进行分割。

案文示例:

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上执行gsubABC因为短划线后面的字总是在变化,会多次出现。此外,匹配单词前面的单词也将始终不同,并且不会始终为TREE。无论在匹配单词前面的单词是什么,我总是想要分开。

如果我执行以下str_extract:

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

然后我匹配XYZ而不是ABC

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

我被困住了。如果需要任何进一步的信息,请告诉我。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

这是一种温和的hacky方式。让我们调用数据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"
相关问题