R 包含一个表达式但不包含另一个表达式的字符串的正则表达式
所以我有这个URL列表,但由于某种原因,我使用的正则表达式不会从列表中删除最后两个URLR 包含一个表达式但不包含另一个表达式的字符串的正则表达式,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/
"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