如正则表达式中所述,可以使用正则表达式来匹配嵌套模式吗?,则无法创建正则表达式来匹配任意嵌套模式。但是是否有可能创建一种算法,该算法将生成“nestness”的第n级正则表达式?
基本上,我想替换trim(whatever)为rtrim(ltrim(whatever))
trim(whatever)
rtrim(ltrim(whatever))
我设法手动创建3个级别(javascript语法):
level[1] = /\(([^()]*)\)/g level[2] = /\(((?:[^()]*\([^()]*\))*[^()]*)\)/g level[3] = /\(((?:(?:(?:[^()]*\([^()]*\))*[^()]*)*\((?:(?:[^()]*\([^()]*\))*[^()]*)*\))*[^()]*)\)/g
以下是一些测试数据:
1st(ddd) + 1st(ddd) 2nd(dd(d)) 3rd(a(b) + (cd(h) + d(dfas) + zzz)) 4th(a(b(c(d)))) 8th(a(b(c(d(e(f(g()))))))
我知道在每个级别都[^()]*需要替换为可以包含括号的不捕获组,但是我不确定如何 将算法推广到第n个级别 …
[^()]*
您可以从理论上更仔细地考虑:嵌套n深度较深的括号匹配是围绕n-1深度小于或等于(至少一个正好n-1)的匹配的括号。
n
n-1
我们可以对正则表达式进行递归定义。让我们X[n]将其作为用于精确嵌套n级别Y[n]的正则表达式,并将其作为包含方括号的字符串的正则表达式,并以任意级别嵌套到n级别,因此:
X[n]
Y[n]
X[n] = \( (Y[n-2] X[n-1])+ Y[n-2] \) Y[n] = [^()]* ( \( Y[n-1] \) [^()]* )*
与Y[0] = X[0] = [^()]*(无嵌套)和X[1] = \([^()]*\)。(我尚未打扰非捕获组等的细节,这些空格只是为了便于阅读。)
Y[0] = X[0] = [^()]*
X[1] = \([^()]*\)
基于此编写算法应该很容易。
这些新的(较少相互递归)定义的正则表达式变长得多(它们是多项式而不是指数)。
令l[n]为的长度X[n],L[n]为的长度Y[n],然后(常数项只是每个字符中的硬编码字符):
l[n]
L[n]
L[n] = 19 + L[n-1] = 19*n + L[0] = 19*n + 6 l[n] = 3 + L[n-2] + l[n-1] + 2 + L[n-2] + 2 = 7 + 2 * L[n-2] + l[n-1] = -57 + 38 * n + l[n-1]
与适当的初始条件l[0]和l[1]。这种形式的递归关系具有二次解,因此仅O(n^2)。好多了。
l[0]
l[1]
O(n^2)
(对于其他人,我以前的定义Y[n]是Y[n] = Y[n-1] | X[n];这种额外的递归意味着X正则表达式的长度为O(2.41^n),这很糟糕。)
Y[n] = Y[n-1] | X[n]
X
O(2.41^n)
(的新定义Y是一个诱人的暗示,即甚至可能存在一种X线性的书写方式n。我不知道,而且我觉得X确切长度的额外限制意味着这是不可能的。)
Y
以下是一些计算上述正则表达式的Python代码,您可以将其转换为javascript,而不会带来太多麻烦。
# abbreviation for the No Parenthesis regex np = "[^()]*" # compute Y[n] from Y[n-1] def next_y(y_n1): return np + "(?:\(" + y_n1 + "\)" + np + ")*" # compute X[n] from X[n-1] and Y[n-2] def next_x(x_n1, y_n2): return "\((?:" + y_n2 + x_n1 + ")+" + y_n2 + "\)" # compute [X[n], Y[n], Y[n-1]] # (to allow us to make just one recursive call at each step) def XY(n): if n == 0: return [np, # X[0] np, # Y[0] ""] # unused elif n == 1: return ["\([^()]*\)", # X[1] next_y(np), # Y[1] np] # Y[0] x_n1, y_n1, y_n2 = XY(n-1) # X[n-1], Y[n-1], Y[n-2] return [next_x(x_n1, y_n2), # X[n] next_y(y_n1), # Y[n] y_n1] # Y[n-1] # wrapper around XY to compute just X[n] def X(n): return XY(n)[0] # wrapper around XY to compute just Y[n] def Y(n): return XY(n)[1]