【问题标题】:Using negative lookahead in ls(pattern = "") in R在 R 中的 ls(pattern = "") 中使用负前瞻
【发布时间】:2021-12-22 09:51:08
【问题描述】:

假设我在内存中有以下对象:

ab
ab_b
ab_pm
ab_pn
c1_ab_b

我只想保留ab_pmab_pn

我尝试在ls() 中使用负前瞻来列出abab_bc1_ab_b 以进行删除:

rm(list = ls(pattern = "ab_?(?!p)")

但是,我得到了错误:

Error in grep(pattern, all.names, value = TRUE) :
  invalid regular expression 'ab_?(?!p)', reason 'Invalid regexp'

我在regex101.com 尝试了我的正则表达式,发现它匹配所有五个对象名称,这表明我的正则表达式并非“无效”,尽管它没有达到我想要的效果。我的问题是:

  1. R 中的ls() 是否支持负前瞻?我知道grep() 需要perl = TRUE 来支持它,但在ls() 帮助文档中没有看到类似的论点。
  2. 如何正确选择我要移除的三个对象?

【问题讨论】:

  • 在 regex101.com 输入正则表达式和测试字符串后,点击左上角的“保存正则表达式”。这将为您提供一个可用于链接的 URL,使读者可以查看您的测试。
  • 感谢 Cary Swoveland 的提示!将来肯定会这样做!

标签: r regex regex-lookarounds ls


【解决方案1】:

由于回溯,您的ab_?(?!p) PCRE 正则表达式与预期不匹配。它匹配ab,然后匹配可选的_,然后尝试否定环视。当环视发现p 发生回溯,并且在_ 之前再次触发前瞻。由于_ 不是p,因此返回匹配项。

正确的 PCRE 正则表达式是 ab(?!_?p),请参阅 regex demo。匹配b 后,正则表达式引擎仅尝试一次前瞻模式,如果它未能匹配可选的_ 后跟p,则整个匹配将失败。

ls 不支持perl=TRUE,因此它只支持不支持环视的默认 TRE 正则表达式库。

你可以使用

ab([^_]p|_[^p]|.?$)

请参阅regex demo详情

  • ab - ab 文字
  • ([^_]p|_[^p]|.?$) - 三种选择之一:
    • [^_]p - 除了_p 之外的任何字符
    • | - 或
    • _[^p] - _ 然后是除 p 之外的任何字符
    • | - 或
    • .?$ - 任何一个可选字符,然后是字符串结尾。

【讨论】:

  • 非常感谢,Wiktor Stribiżew,指点我回溯 - 我对正则表达式相当陌生,因此必须阅读更多相关信息。还要感谢您阐明正确的负正则表达式。由于我的对象名称中没有“任何字符,但 _ 然后 p”模式,我将您的解决方案简化为“ab(_[^p]|$)”,这似乎适用于 regex101.com。如果我忽略了什么,请告诉我。再次感谢!
  • @elarry 如果ab(_[^p]|$) 符合您的需要,可以保留。它只匹配ab,然后要么需要字符串结尾,要么匹配_,然后匹配p以外的任何字符。因此,它不会匹配 ab_,例如。
【解决方案2】:

ls 使用grep(pattern, all.names, value = TRUE),因此它不支持包括前瞻在内的 perl 扩展。不过,您可以通过将ls 包装在grep 中来在外部处理它:

vec <- ls(pattern = "^ab_")
# vec <- c("ab","ab_b","ab_pm","ab_pn","c1_ab_b")
grep("ab_(?=p)", vec, perl = TRUE, value = TRUE)
# [1] "ab_pm" "ab_pn"

所以也许是单行:

grep("ab_(?=p)", ls(pattern = "^ab_"), value = TRUE, perl = TRUE)

这是一个双grep(一次在ls内,一次在外面);人们总是可以让它更直接一点

grep("ab_(?=p)", ls(), value = TRUE, perl = TRUE)

【讨论】:

  • 非常感谢 r2evans 的解释!我怎么没想到将 ls() 包装在 grep() 中!但是,我想选择其他三个变量进行删除,所以您只回答了我的一个问题。无论如何,非常感谢您的帮助! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 2021-11-09
相关资源
最近更新 更多