Regex 正则表达式的时间复杂性和允许模式查找中的抖动
要查找字符串中的模式,我有以下代码。在其中,find.string查找最大长度的子字符串,但必须遵守以下条件:(1)子字符串必须至少连续重复th次,(2)子字符串长度不得超过lenRegex 正则表达式的时间复杂性和允许模式查找中的抖动,regex,string,r,pattern-matching,time-complexity,Regex,String,R,Pattern Matching,Time Complexity,要查找字符串中的模式,我有以下代码。在其中,find.string查找最大长度的子字符串,但必须遵守以下条件:(1)子字符串必须至少连续重复th次,(2)子字符串长度不得超过len reps <- function(s, n) paste(rep(s, n), collapse = "") # repeat s n times find.string <- function(string, th = 3, len = floor(nchar(string)/th)) { f
reps <- function(s, n) paste(rep(s, n), collapse = "") # repeat s n times
find.string <- function(string, th = 3, len = floor(nchar(string)/th)) {
for(k in len:1) {
pat <- paste0("(.{", k, "})", reps("\\1", th-1))
r <- regexpr(pat, string, perl = TRUE)
if (attr(r, "capture.length") > 0) break
}
if (r > 0) substring(string, r, r + attr(r, "capture.length")-1) else ""
}
reps效率不高,但塔达:
reps <- function(s, n) paste(rep(s, n), collapse = "") # repeat s n times
find.string <- function(string, th = 3, len = floor(nchar(string)/th)) {
found <- FALSE
for(sublen in len:1) {
for(inlen in 0:sublen) {
pat <- paste0("((.{", sublen-inlen, "})(.)(.{", inlen, "}))", reps("(\\2.\\4)", th-1))
r <- regexpr(pat, string, perl = TRUE)
if (attr(r, "capture.length")[1] > 0){
found = TRUE
break;
}
}
if(found) break
}
if (r > 0) substring(string, r, r + attr(r, "capture.length")[1] - 1) else ""
}
find.string("a0cc0vaaaabaaadbaaabbaa00bvw"); # returns "aaaab"
reps基本上有两种正则表达式算法类型,Perl风格(有很多复杂的回溯)和Thompson NFA
要确定哪个引擎R使用R的svn回购,请参见:
*根回购:
\R-exp-uncmin\src\regex
我在里面翻了一下,发现了一个名为“engine.c”的文件,乍一看,它看起来不像汤普森NFA,但我没花多长时间就看完了
无论如何,第一个链接深入讨论了一般的复杂性问题,应该会让您对regex解析如何在引导过程中工作有一个很好的了解 您可以查看一下允许“近似字符串匹配(模糊匹配)”的agrep
。您可能遇到的主要问题是TRE库似乎不支持反向引用的近似匹配(例如\\1
),AFAIK。这是不幸的,否则对上述代码的一个小改动就可以解决您的问题(例如,rep(“(\\1){<2}”,th-1)
。希望我是错的,有一种方法可以实现这一点,但简单的测试表明不行。另外,请注意,您不能使用perl=t
进行近似匹配,因此可能需要进行一些其他更改。当前的答案没有包含足够的详细信息?对我来说,它们似乎没有包含任何详细信息。因为它们不存在如果有任何数量的“抖动”,你可能会考虑使用机器学习方法在适当的一批数据上训练而不是正则表达式匹配。