R 包含一个表达式但不包含另一个表达式的字符串的正则表达式

R 包含一个表达式但不包含另一个表达式的字符串的正则表达式,r,R,所以我有这个URL列表,但由于某种原因,我使用的正则表达式不会从列表中删除最后两个URL "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline- Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632" "https://www.homedepot.com/p/

所以我有这个URL列表,但由于某种原因,我使用的正则表达式不会从列表中删除最后两个URL

"https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline- Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"                 
"https://www.homedepot.com/p/Reliance-Controls-40-ft-30-Amp-Generator-Power-Cord-PC3040/202216500"                                                                            
"https://www.homedepot.com/p/Champion-Power-Equipment-25-ft-120-Volt-Generator-Power-Cord-48034/203501795" 
我想消除任何包含“cord”和不包含“and”的URL。因此,最终我希望表达式只返回第一个URL。我在完整列表中还有其他不包含我想要保留的“cord”的URL,所以我不能仅仅删除没有“cord”和“and”的任何内容

这是我一直在尝试的,但它仍然返回所有三个URL


任何帮助都会很好。谢谢大家!

可能有一个更好的“单一”正则表达式来实现这一点,但这里有一个分为两部分的解决方案

首先,识别所有包含“跳线”的

然后,我们使用您需要的组合对URL向量进行子集,在本例中,没有“cord”而没有“and”


您正在寻找
^((?!and)。)*跳线((?!and)。*$
我使用的跳线不包含和,因为和可能位于跳线之前或之后

你可以做:

a[!grepl("^((?!and).)*Cord((?!and).)*$",a,ignore.case = T,perl=T)]
[1] "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline-Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"
或:

为了更快地进行操作,您可以决定不捕获组,从而使用:

^(?:(?!and)。*跳线(?:(?!and)。


我喜欢用我的思维方式写正则表达式。我把这个问题分成了两种情况

案例1:你有一些数字,然后是“和”,然后可能是一些数字,然后是“线”,然后可能是一些数字。 案例2:你有一些数字,然后是“Case”,然后可能是一些数字,然后是“and”,然后可能是一些数字

将每种情况放在分组括号中,并在它们之间加上or

为“and”和“case”的正则表达式添加一些大小写敏感度。我只是让第一个字符不区分大小写,但是如果需要,你可以做得更多

str_detect(a, "(.+[Cc]ord.*[Aa]nd.*)|(.+[Aa]nd.*[Cc]ord.*)")
有关其工作原理的示例和说明: [


这一切都假设您有一个工作链接,并且在“and”或“cord”之前必须有诸如“http://”之类的内容。我不认为复杂的正则表达式是解决这个问题的方法,它在资源中更昂贵,可读性较差,并且不能推广到更多约束

以下是一个基本解决方案和Onyanbu基准测试的更新(还添加了我更正的Felipe解决方案):


这是一个解决方案,但不是针对我的情况,因为正如我提到的,URL列表的其余部分有我想要的不包含“cord”的URL。所以我想要那些URL和所有包含“cord”而不包含“and”的URL。我可以创建两个列表并将它们合并,但我正在寻找一个更干净的方法。@MtnBee您只需对条件的第二部分求反即可。
str_detect(a, regex('and', ignore_case = T))
[1]  TRUE FALSE FALSE
    a[str_detect(a, regex('cord', ignore_case = T)) &
           str_detect(a, regex('and', ignore_case = T))]
[1] "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline-Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"
a[!grepl("^((?!and).)*Cord((?!and).)*$",a,ignore.case = T,perl=T)]
[1] "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline-Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"
grep("^((?!and).)*Cord((?!and).)*$",a,ignore.case = T,perl=T,invert = T,value = T)
[1] "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline-Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"
 a = rep(a,1000)
 microbenchmark::microbenchmark(
    a=grepl("^((?!and).)*Cord((?!and).)",a,ignore.case = T,perl=T),
    b=grepl("^(?:(?!and).)*Cord(?:(?!and).)",a,ignore.case = T,perl=T)
  )
Unit: milliseconds
 expr      min       lq     mean   median       uq      max neval cld
    a 8.604448 8.631186 8.693752 8.656785 8.716235 9.077194   100   b
    b 7.915523 7.944821 7.999503 7.967861 7.998580 9.221692   100  a
str_detect(a, "(.+[Cc]ord.*[Aa]nd.*)|(.+[Aa]nd.*[Cc]ord.*)")
a[grepl("and",a) & grepl("cord",a,TRUE)]
# [1] "https://www.homedepot.com/p/Champion-Power-Equipment-7500-Watt-Gasoline-Powered-Electric-Start-Portable-Generator-and-25-ft-Extension-Cord-100219/206268632"

a = rep(a,1000)

microbenchmark::microbenchmark(
  # ad=str_detect(a, "(.+[Cc]ord.*[Aa]nd.*)|(.+[Aa]nd.*[Cc]ord.*)"), # too slow
  o1 = a[!grepl("^((?!and).)*Cord((?!and).)",a,ignore.case = T,perl=T)],
  o2 = a[!grepl("^(?:(?!and).)*Cord(?:(?!and).)",a,ignore.case = T,perl=T)],
  fe = a[!str_detect(a, regex('cord', ignore_case = T)) |
           str_detect(a, regex('and', ignore_case = T))],
  mm = a[grepl("and",a,perl = T) | !grepl("[Cc]ord",a,TRUE, perl=T)],
  unit = "relative"
)
# Unit: relative
#  expr      min       lq     mean   median       uq      max neval
#    o1 5.789945 5.735891 5.591111 5.767107 5.620815 5.863636   100
#    o2 5.338966 5.302216 5.187022 5.318472 5.210676 5.422635   100
#    fe 2.609088 2.777571 2.753290 2.838782 2.815973 2.664935   100
#    mm 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   100