这是A regex to detect periodic strings的后续行动。
字符串
p
的句点w
是任意正整数p
,w[i]=w[i+p]
每当定义这个等式的两边时。让per(w)
表示 最小句点w
的大小。我们说字符串w
是 周期性iffper(w) <= |w|/2
。
非正式地,周期性字符串只是一个由至少重复一次的另一个字符串组成的字符串。唯一的复杂因素是,在字符串的末尾,我们不需要重复字符串的完整副本,只要它至少重复一次即可。
例如,考虑字符串x = abcab
。 per(abcab) = 3
为x[1] = x[1+3] = a
,x[2]=x[2+3] = b
并且没有较小的期限。因此字符串abcab
不是周期性的。但是,字符串ababa
定期为per(ababa) = 2
。
作为更多示例,abcabca
,ababababa
和abcabcabc
也是定期的。
@horcruz等人给出了一个非常好的正则表达式来识别周期性字符串。它是
\b(\w*)(\w+\1)\2+\b
我想在更长的字符串中找到所有最大周期性子字符串。这些在文献中有时被称为 run 。
正式子字符串
w
是最大周期性子字符串,如果它是周期性的,既不是w[i-1] = w[i-1+p]
也不是w[j+1] = w[j+1-p]
。非正式地,&#34;运行&#34;不能包含在更大的&#34; run&#34; 在同一时期。
字符串T = atattatt
的四个最大周期性子串(运行)为T[4,5] = tt
,T[7,8] = tt
,T[1,4] = atat
,T[2,8] = tattatt
。
字符串T = aabaabaaaacaacac
包含以下7个最大周期性子串(运行):
T[1,2] = aa
,T[4,5] = aa
,T[7,10] = aaaa
,T[12,13] = aa
,T[13,16] = acac
,T[1,8] = aabaabaa
,T[9,15] = aacaaca
。
字符串T = atatbatatb
包含以下三个运行。他们是:
T[1, 4] = atat
,T[6, 9] = atat
和T[1, 10] = atatbatatb
。
是否有正则表达式(带反向引用)将捕获所有最大值 周期性子串?
我真的不介意正则表达式的哪种风格,但如果它有所作为,那么Python模块re
支持的任何内容。但是,如果这样可以解决问题,我甚至会对PCRE感到满意。
让我们将正则表达式版本扩展为非常强大的https://pypi.python.org/pypi/regex。例如,这支持可变长度的lookbehinds。
答案 0 :(得分:2)
这应该使用Python的re
模块:
(?<=(.))(?=((\w*)(\w*(?!\1)\w\3)\4+))
小提琴:https://regex101.com/r/aA9uJ0/2
注意:
#
。如果这是一个问题,应该可以在正则表达式中解决它。说明:
(?<=(.))
- 查看最大周期子字符串之前的字符;被捕获为第1组(?=...)
- 前瞻,以确保匹配重叠的模式;见How to find overlapping matches with a regexp? (...)
- 捕获最大周期性子串(组2)(\w*)(\w*...\w\3)\4+
- @ horcruz&#39;正则表达式,由OP提出(?!\1)
- 对组1进行否定预测以确保周期性子字符串最大 正如@ClasG指出的那样,我的正则表达式的结果可能不完整。当两次运行以相同的偏移量开始时会发生这种情况例子:
aabaab
有3次投放:aabaab
,aa
和aa
。前两次运行以相同的偏移量开始。我的正则表达式将无法返回最短的正则表达式。atatbatatb
有3次投放:atatbatatb
,atat
,atat
。同样的问题;我的正则表达式只会返回第一次和第三次运行。在正则表达式中这可能无法解决。据我所知,没有正则表达式引擎能够返回两个以相同偏移量开始的不同匹配。
我看到两种可能的解决方案:
答案 1 :(得分:0)
我认为这是不可能的。正则表达式无法执行复杂的非确定性作业,即使使用反向引用也是如此。你需要一个算法。
答案 2 :(得分:0)
这种取决于您的输入标准......没有无限的字符串..使用后向引用,您将能够创建您希望匹配的模式的最后出现次数的合适表示。 \ 我个人会定义输入长度的桶,然后填充它们。
然后我会使用自动机来查找存储桶中的模式,然后最终将它们合并为更大的模式。
在这种情况下,RegEx不会有多快,它能够以多快的速度识别模式并消除无效标准。