使用r匹配字符串中第二个重复单词的正则表达式



我有以下字符串向量,我需要匹配第二个重复的单词,而不是第一个,没有空间。

names_vec <- c("Linda Smith","Elizabeth Olsen Green Elizabeth Olsen Green",
"Eva Ferguson","Charlize Martinez White Charlize Martinez White",
"digital copy solutions digitals",
"honor security services honor")

结果向量应该是:答:我的错误有误会。当在"荣誉安全服务"中匹配第二副本时,"荣誉";最后一个Word是必须匹配和删除的。

matched_vec <- c("Elizabeth Olsen Green","Charlize Martinez White","honor security services")

我尝试了不同的方法,但都没有成功。下面的代码匹配第一个出现的单词,但我需要最后一个,因为我想删除最后一个重复的单词,而不是第一个。

下面的代码获取括号内的内容,我想要其他重复的单词。

str_view_all(names_vec , "(\b\S+\s*\b)(?=.*\b\1\b)", match = TRUE)
[Elizabeth Olsen Green] Elizabeth Olsen Green 
[Charlize Martinez White] Charlize Martinez White
[honor] security services honor

我使用的正则表达式匹配每个字符串的第一个重复的单词,从字符串的开始有重复。

我的期望是匹配字符串的第二个重复的单词,所以它必须从右向左搜索并匹配所有第二个重复的单词。

人们会问我,为什么要麻烦。问题是我有一些公司名称,如果你从左到右数的话,通常我想要删除的重复单词是第二个或最后一个。

这是另一种可以考虑的方法

library(stringr)
str_view_all_Mod <- function(string, pattern, match = NA) 
{
if(identical(match, TRUE)) {
string <- string[str_detect(string, pattern)]
}
else if (identical(match, FALSE)) {
string <- string[!str_detect(string, pattern)]
}
loc <- str_locate_all(string, pattern)
string_list <- Map(loc = loc, string = string, function(loc, 
string) {
if (nrow(loc) == 0) 
return(string)
for (i in rev(seq_len(nrow(loc)))) {
str_sub(string, loc[i, , drop = FALSE]) <- paste0(" /// ", 
str_sub(string, loc[i, , drop = FALSE]), " /// ")
}
string
})
string <- unlist(string_list)
string <- str_remove_all(string, pattern = "///  ///")
return(string)
}
reverse_String <- function(text)
{
splits <- strsplit(text, "")[[1]]
reversed <- rev(splits)
final_result <- paste(reversed, collapse = "")
return(final_result)
}
names_vec <- c("Linda Smith","Elizabeth Olsen Green Elizabeth Olsen Green Allo bonjour Elizabeth Olsen Green",
"Eva Ferguson","Charlize Martinez White Charlize Martinez White",
"digital copy solutions digitals",
"honor security services honor")
nb_Text <- length(names_vec)
names_vec_rev <- rep(NA, nb_Text)
for(i in 1 : nb_Text)
{
names_vec_rev[i] <- reverse_String(names_vec[i])
}
text <- str_view_all_Mod(names_vec_rev, "(\b\S+\s*\b)(?=.*\b\1\b)", match = TRUE)
text <- stringr::str_extract(text, "///[^/]*///")
text <- stringr::str_remove_all(text, "///")
text <- lapply(X = text, FUN = reverse_String)
unlist(text)

[1] " Elizabeth   Olsen   Green "   " Charlize   Martinez   White " " honor " 

以下似乎是一个紧凑的stringr解决方案:

str_remove(names_vec, "(.*).*(?=\b\1\b)")
[1] ""   "Elizabeth Olsen Green"   ""   "Charlize Martinez White"   ""   "honor" 

在这里,我们删除了所有重复的内容以及后面的内容,从而只保留了实际的repeat或duplicate本身。为了识别欺骗,我们使用正向正向的(?=...)和反向引用的\1包裹在字\b边界中。

如果你不想要空字符串,通过子集删除它们:

matched_vec <- str_remove(names_vec, "(.*).*(?=\b\1\b)")
matched_vec[matched_vec != ""]
[1] "Elizabeth Olsen Green"   "Charlize Martinez White" "honor"

或者考虑tidyverse解决方案:

data.frame(names_vec) %>%
extract(names_vec, into = c("1st","2nd"), "(.*).*(\b\1\b)", remove = FALSE) %>%
select(-"1st")
names_vec                     2nd
1                                     Linda Smith                        
2     Elizabeth Olsen Green Elizabeth Olsen Green   Elizabeth Olsen Green
3                                    Eva Ferguson                        
4 Charlize Martinez White Charlize Martinez White Charlize Martinez White
5                 digital copy solutions digitals                        
6                   honor security services honor                   honor

这里我们使用tidyrextract函数将字符串划分为两个捕获组,一个用于1st部分,一个用于2nd部分,这是1st的重复;重复的由反向引用\1

标识。

您可以使用stringi::stri_reverse来反转字符。然后我在gsub中使用您的正则表达式并删除第一次重复,实际上是最后一次重复,并再次反转结果。

stringi::stri_reverse(
gsub("(\b\S+\s*\b)(?=.*\b\1\b)", "",
stringi::stri_reverse(names_vec), perl=TRUE) )
#[1] "Linda Smith"                     "Elizabeth Olsen Green "         
#[3] "Eva Ferguson"                    "Charlize Martinez White "       
#[5] "digital copy solutions digitals" "honor security services "       

或者只使用sub:

sub("(\b\S.*\b)(.*)\b\1\b", "\1\2", names_vec)
#[1] "Linda Smith"                     "Elizabeth Olsen Green "         
#[3] "Eva Ferguson"                    "Charlize Martinez White "       
#[5] "digital copy solutions digitals" "honor security services "       

相关内容

  • 没有找到相关文章

最新更新