Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在正则表达式中创建第n层嵌套模式的算法_Javascript_Regex_Algorithm_Recursion - Fatal编程技术网

Javascript 在正则表达式中创建第n层嵌套模式的算法

Javascript 在正则表达式中创建第n层嵌套模式的算法,javascript,regex,algorithm,recursion,Javascript,Regex,Algorithm,Recursion,如中所述,不可能创建正则表达式来匹配任意嵌套模式。但是,有没有可能创建一个算法来生成第n级“嵌套”的正则表达式 基本上,我想用rtrim(ltrim(whatever))替换trim(whatever) 我设法手动创建了3个级别(javascript语法): level[1]=/\([^()]*)\)/g 级别[2]=/\((((?:[^()]*\([^()]*\)*[^()]*])\)/g 级别[3]=/\((((?:(?:(?:[^()]*\([^()]*\)*\((?:(?:[^()]*\

如中所述,不可能创建正则表达式来匹配任意嵌套模式。但是,有没有可能创建一个算法来生成第n级“嵌套”的正则表达式

基本上,我想用
rtrim(ltrim(whatever))替换
trim(whatever)

我设法手动创建了3个级别(javascript语法):

level[1]=/\([^()]*)\)/g
级别[2]=/\((((?:[^()]*\([^()]*\)*[^()]*])\)/g
级别[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
deep的匹配只是围绕
n-1
或更低深度的匹配的括号(至少有一个正好
n-1
deep)

我们可以给出正则表达式的递归定义。设
X[n]
为精确嵌套
n
级别的正则表达式,
Y[n]
为包含任何嵌套级别的括号的字符串的正则表达式,直到
n
级别,因此:

X[n] = \( (Y[n-2] X[n-1])+ Y[n-2] \)

Y[n] = [^()]* ( \( Y[n-1] \) [^()]* )*
使用
Y[0]=X[0]=[^()]*
(无嵌套)和
X[1]=\([^()]*\)
。(我还不在乎非捕获组等的细节,这些空间只是为了可读性。)

基于此编写算法应该很容易


来自这些新定义(较少相互递归)的正则表达式变得更长更慢(它们是多项式而不是指数)

假设
l[n]
X[n]
的长度,
l[n]
Y[n]
的长度,那么(常数项只是每个常数项中的硬编码字符):

使用
l[0]
l[1]
的适当初始条件。这种形式的递推关系有二次解,所以这只是
O(n^2)
。好多了

(对于其他人,我以前对
Y[n]
的定义是
Y[n]=Y[n-1]|X[n]
;这个额外的递归意味着
X
正则表达式的长度是
O(2.41^n)
,这很糟糕。)

(对
Y
的新定义是一个诱人的暗示,甚至可能有一种书写
X
的方式,在
n
中是线性的。不过我不知道,我感觉对
X
的额外限制精确长度意味着这是不可能的。)


下面是一些计算上述正则表达式的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]

谢谢,O()不是问题,我希望没有人会使用超过10个嵌套括号,我会在周末看一看:)@deathApril,我刚刚通过更改
Y
的定义大大改进了答案。这将
n=10
的正则表达式的大小从~45000减少到~1500(因此,即使对于
10
来说,O()也使正则表达式变得巨大!)。(我知道你并不担心大型
n
,但我觉得这个问题很有趣(谢谢你问!),所以我还是在做分析。)@deathApril,现在有一些代码(虽然是Python而不是Javascript)。很高兴听到这个问题对你来说很有趣-我的工作量更少;)python还可以,我只需运行它并在记事本++宏中使用生成的正则表达式(或者我创建一个简单的web应用程序来实现它,如果其他团队成员想使用它的话)——我会在对它进行更多测试后接受;)
# 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]