如何在不知道 R 中的单词的情况下匹配某个字符后的单词?
How to match a word after a certain character with out knowing the word in R?
我想匹配文本中 -
之后的单词,如果匹配的单词是另一个单词的结尾,那么我想在单词和匹配的单词之间进行拆分。
文本示例:
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
我不想在 ABC
上做一个 grepl
和一个 gsub
因为破折号后面的词总是在变化并且会出现多次。此外,匹配词前面的词也总是不同的,并不总是 TREE
。无论匹配到的词前面是什么词,我总是想拆分。
如果我执行以下操作 str_extract:
str_extract(df, "(?<=-\s)\w+")
然后我匹配 XYZ
而不是 ABC
.
我只想匹配 -
之后的单词,如果它也在另一个单词的末尾,但我又不知道另一个单词是什么。
我不知道该怎么办。如果需要任何进一步的信息,请告诉我。任何帮助将不胜感激。
这是一种稍微老套的方法。我们称数据为 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+")
使用这些模式查找所有在模式之前具有非白色space 字符且在模式之后具有 space 字符的单词(即需要 spaces 的单词):
words <- str_extract_all(s, paste0('[A-Za-z0-9]+', pat[[1]], '\s'))
通过将模式替换为 space 然后再替换模式,在这些词中插入 spaces。要一次完成所有操作,您需要使用 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"
我想匹配文本中 -
之后的单词,如果匹配的单词是另一个单词的结尾,那么我想在单词和匹配的单词之间进行拆分。
文本示例:
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
我不想在 ABC
上做一个 grepl
和一个 gsub
因为破折号后面的词总是在变化并且会出现多次。此外,匹配词前面的词也总是不同的,并不总是 TREE
。无论匹配到的词前面是什么词,我总是想拆分。
如果我执行以下操作 str_extract:
str_extract(df, "(?<=-\s)\w+")
然后我匹配 XYZ
而不是 ABC
.
我只想匹配 -
之后的单词,如果它也在另一个单词的末尾,但我又不知道另一个单词是什么。
我不知道该怎么办。如果需要任何进一步的信息,请告诉我。任何帮助将不胜感激。
这是一种稍微老套的方法。我们称数据为 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+")
使用这些模式查找所有在模式之前具有非白色space 字符且在模式之后具有 space 字符的单词(即需要 spaces 的单词):
words <- str_extract_all(s, paste0('[A-Za-z0-9]+', pat[[1]], '\s'))
通过将模式替换为 space 然后再替换模式,在这些词中插入 spaces。要一次完成所有操作,您需要使用 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"