在函数体中查找函数调用的正则表达式 请将代码< >读取>表>代码>作为文本文件,用以下代码创建: sink("readTable.txt") body(read.table) sink()
使用正则表达式,我想在在函数体中查找函数调用的正则表达式 请将代码< >读取>表>代码>作为文本文件,用以下代码创建: sink("readTable.txt") body(read.table) sink(),r,regex,R,Regex,使用正则表达式,我想在“readTable.txt”中找到所有形式为foo(a,b,c)(但具有任意数量的参数)的函数调用。也就是说,我希望结果包含read.table主体中所有被调用函数的名称。这包括形式为 foo(a,bar(b,c))。保留字(return,for,等等)和使用回号('='(),'+'(),等等)的函数可以包括在内,因为我以后可以删除它们 一般来说,我在寻找模式text(或text(),然后是可能的嵌套函数,如text1(text2(),但如果它是一个参数,而不是一个函数,
“readTable.txt”
中找到所有形式为foo(a,b,c)
(但具有任意数量的参数)的函数调用。也就是说,我希望结果包含read.table
主体中所有被调用函数的名称。这包括形式为foo(a,bar(b,c))
。保留字(return
,for
,等等)和使用回号('='()
,'+'()
,等等)的函数可以包括在内,因为我以后可以删除它们
一般来说,我在寻找模式text(
或text(
),然后是可能的嵌套函数,如text1(text2(
),但如果它是一个参数,而不是一个函数,则跳过文本。这是我目前所处的位置。很接近,但不是很接近
x <- readLines("readTable.txt")
regx <- "^(([[:print:]]*)\\(+.*\\))"
mat <- regexpr(regx, x)
lines <- regmatches(x, mat)
fns <- gsub(".*( |(=|(<-)))", "", lines)
head(fns, 10)
# [1] "default.stringsAsFactors()" "!missing(text))"
# [3] "\"UTF-8\")" "on.exit(close(file))" "(is.character(file))"
# [6] "(nzchar(fileEncoding))" "fileEncoding)" "\"rt\")"
# [9] "on.exit(close(file))" "\"connection\"))"
Perl模式下的递归正则表达式 在一般情况下,我相信您已经意识到尝试匹配此类结构的危险:如果您的文件包含您不想匹配的
if()
之类的内容,该怎么办
尽管如此,我相信这个递归正则表达式符合我所理解的需求
[a-z]+(\((?:`[()]|[^()]|(?1))*\))
看
我对R
语法还不是很熟悉,但类似的东西应该可以使用,您可以调整函数名和参数以满足您的需要:
grepl("[a-z]+(\\((?:`[()]|[^()]|(?1))*\\))", subject, perl=TRUE);
解释
匹配左括号前的字母[a-z]+
启动组1(
匹配左括号\(
启动一个将重复的非捕获组。捕获组匹配几种可能性:(?:
匹配BACKTICK+BACKTICK[()]
或(
(抱歉,不知道如何使BACKTICK显示在此编辑器中)
或匹配一个非括号字符|[^()]
或匹配第1组括号定义的模式(递归)|(?1)
关闭非捕获组,重复零次或多次)*
匹配右括号\)
结束第1组)
call.ignore <-c("[[", "[", "&","&&","|","||","==","!=",
"-","+", "*","/", "!", ">","<", ":")
find.funcs <- function(f, descend=FALSE) {
if( is.function(f)) {
return(find.funcs(body(f), descend=descend))
} else if (is(f, "name") | is.atomic(f)) {
return(character(0))
}
v <- list()
if (is(f, "call") && !(deparse(f[[1]]) %in% call.ignore)) {
v[[1]] <- deparse(f)
if(!descend) return(v[[1]])
}
v <- append(v, lapply(as.list(f), find.funcs, descend=descend))
unname(do.call(c, v))
}
如果要查找其他函数的函数调用,可以将down=
参数设置为TRUE
我确信有很多软件包使这更容易,但是我只是想说明它是多么的简单。
如果它不一定是正则表达式的解决方案,请考虑<代码>代码工具::WalkCudio。@ GSee,现在很有意思,很有用。对于这个问题,我想坚持ReEX方法。这是我的一个问题。d类,我只是在尝试改进我以前的答案。不过,请随意将该函数作为答案发布,这很酷。您可以提供您搜索的样本输入数据作为匹配项吗?请查看mvbutils包。我想继续使用regex方法
您可以通过添加字符串从我的答案中进行测试。d不要让不同的颜色困扰你。整个字符串都是匹配的,但中流的颜色变化表明组1的匹配位置(我们不需要担心)这是否涵盖了参数是否是另一个函数调用?使用“re”模块在python中尝试这一点。抱怨?1是否可以将其构建为树或其他东西?如果需要,我可以问另一个问题。如果函数是多行的,最好将其存储在列表中。$符号可能也是一个问题:na.omit(github.df$links)
。我想构建一个名为traceforward
的函数,该函数跟踪所有唯一的函数,可能按“库”排序……使用search
find.funcs(read.table)
# [1] "default.stringsAsFactors()"
# [2] "missing(file)"
# [3] "missing(text)"
# [4] "textConnection(text, encoding = \"UTF-8\")"
# [5] "on.exit(close(file))"
# [6] "is.character(file)"
# ...