在R中匹配字符串的开头但不匹配结尾

3

如何匹配所有以plan_开头且不以template结尾的单词,而不使用invert = TRUE?在下面的示例中,我只想匹配第二个字符串。 我尝试了负向先行断言,但它不起作用,可能是因为贪婪性?

names <- c("plan_x_template", "plan_x")
grep("^plan.*(?!template)$", 
  names, 
  value = TRUE, perl = TRUE
)
#> [1] "plan_x_template" "plan_x"    

我的意思是,也可以通过两个正则表达式调用来解决这个问题,但我想看看另一种方法的工作原理 :-)

is_plan <- grepl("^plan_", names)
is_template <- grepl("_template$", names)
names[is_plan & !is_template]
#> [1] "plan_x"

这个 grep("^plan_[A-Za-z]+\\b", names, value = TRUE) 对你来说有效吗? - undefined
1个回答

5

你可以使用

names <- c("plan_x_template", "plan_x")
grep("^plan(?!.*template)", 
  names, 
  value = TRUE, perl = TRUE
)

请查看R在线演示 ^plan(?!.*template)模式匹配到以下内容:
  • ^ - 字符串的开头
  • plan - 一个plan子字符串
  • (?!.*template) - 负向前瞻,如果当前位置左侧紧挨着0个或多个非换行符的字符(因为使用了perl=TRUE并且该模式是用PCRE引擎处理的,与默认的grep TRE正则表达式引擎不同,.不能匹配所有可能的字符),后跟template子字符串,则匹配失败。
注意: 对于多行字符串,您需要在正则表达式中使用DOTALL修饰符,例如:"(?s)^plan(?!.*template)"

1
谢谢。那么我可以将负向先行断言“从里到外”读取吗?也就是说,如果.*template匹配成功,(?!.*template)将不匹配,反之亦然? - undefined
@LorenzWalthert 如果需要相反的行为,您可以使用 invert = TRUE(?!.*template) 将匹配那些字符串中后面缺少 template 的情况。(?=.*template)(正向预查)将匹配那些字符串中当前位置左边有 template 的情况。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接