Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.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 对于正则表达式模式,如何确定与该模式匹配的最长字符串的长度?_Javascript_C#_Regex_Algorithm - Fatal编程技术网

Javascript 对于正则表达式模式,如何确定与该模式匹配的最长字符串的长度?

Javascript 对于正则表达式模式,如何确定与该模式匹配的最长字符串的长度?,javascript,c#,regex,algorithm,Javascript,C#,Regex,Algorithm,有了Regex模式regexpatern,如何确定与regexpatern匹配的最长字符串的长度 想象中的int longestlingthstring模式应如下所示: Assert.Equals(LongestLength("[abc]"), 1); Assert.Equals(LongestLength("(a|b)c?"), 2); Assert.Equals(LongestLength("d*"), int.MaxValue); // Or throws NoLongestLength

有了Regex模式regexpatern,如何确定与regexpatern匹配的最长字符串的长度

想象中的int longestlingthstring模式应如下所示:

Assert.Equals(LongestLength("[abc]"), 1);
Assert.Equals(LongestLength("(a|b)c?"), 2);

Assert.Equals(LongestLength("d*"), int.MaxValue); // Or throws NoLongestLengthException

虽然问题是C语言,但C语言和JavaScript语言的答案都很好。

因此,我如何实现这个功能,首先要创建键值对数据类型。然后用每种类型的正则表达式语法填充数据类型。因此,关键是正则表达式语法,例如:*。该值将是它将为匹配字符串的可能长度增加多少。因此,键:*的值为int.maxvalue。因此,您可以在列表中循环,并在传入的正则表达式中搜索任何语法,将找到的所有值相加并返回它。但是,您必须记住,有些语法是转义的,因此无法计算它们。以及一些语法自动将可能的长度设置为int.maxvalue*、+,等等。。。因此,请首先检查这些语法,以便在找到这些类型的正则表达式语法时,可以自动发回int.maxvalue

因此,我将如何执行此函数,首先创建键值对数据类型。然后用每种类型的正则表达式语法填充数据类型。因此,关键是正则表达式语法,例如:*。该值将是它将为匹配字符串的可能长度增加多少。因此,键:*的值为int.maxvalue。因此,您可以在列表中循环,并在传入的正则表达式中搜索任何语法,将找到的所有值相加并返回它。但是,您必须记住,有些语法是转义的,因此无法计算它们。以及一些语法自动将可能的长度设置为int.maxvalue*、+,等等。。。因此,请首先检查这些语法,以便在找到这些类型的正则表达式语法时,可以自动发回int.maxvalue

只使用运算符?、*和+以及|,再加上括号、字符类,当然还有普通字符,这对于a来说非常简单。事实上,即使\1样式的反引用不是正则表达式的正式定义的一部分,并且使正则表达式的某些问题变得复杂,也可以毫无问题地处理

正则表达式只是树结构的压缩编码,类似于数学公式是描述算术的树结构的压缩编码。在每对相邻的字符之间,都有一个隐式follows操作符,它对应于一个具有两个子节点的节点,一个是其左侧的子节点,另一个是正则表达式的整个剩余部分;由|个字符分隔的子区域序列对应于一个alt节点,其子节点的数量与备选方案的数量相同,即比|个字符的数量多一个,而每个其他操作符只有一个子区域,即它操作的子区域,并且每个普通字符或字符类根本没有子节点。要计算匹配字符串的最大长度,您只需对该树结构进行自底向上的遍历,在每个节点贪婪地分配匹配该节点的最长字符串的长度,给定匹配其子节点的最长字符串的知识

确定与此树中任何给定节点匹配的最长字符串长度的规则如下:

followsx,y-xy:maxlenx+maxleny alta,b,…,z a | b |…| z:MaxLena,maxlenb,…,maxlenz maybex?:maxlenx repx*或posrepx+:无穷大 任何其他单个字符或字符类[…]:1 \1-style backreferences:对应括号表达式的maxlen 一个结果是,除非转义或字符类的一部分,否则任何地方都存在*或+显然会导致无限向上传播到树上,直到它到达根

例子 第二个例子:

Regex: (a|b|de)c?
"Function call" syntax: follows(alt(a, b, follows(d, e)), maybe(c))
As a tree:

     follows
     /     \
   alt     maybe
  / | \        \
 a  b follows   c
       /  \
      d    e
对于第二个正则表达式/树,自下而上的遍历将为叶节点a、b、d、e和c分配一个maxlen为1的值;然后,底部跟随节点的最大值为1+1=2;然后alt节点的maxlen为max1,1,2=2;可能节点的最大值为1;最顶层节点的maxlen为2+1=3,因此整个正则表达式的maxlen为2+1=3


如果您指的是允许其他Perl风格增强功能的正则表达式,那么它可能会变得更加复杂,因为局部最优的长度选择可能会导致全局次优的长度选择。我曾经认为,Perl风格的扩展甚至可能使正则表达式图灵完整,这意味着通常不可能确定是否存在任何匹配字符串,但似乎表明情况并非如此,除非您在{…}中允许构造。

对于一个只使用运算符?、*和+和|,加上括号、字符类,当然还有普通字符的函数,它非常简单。事实上,即使是\1样式的反向引用也不属于 正则表达式的形式化定义,并使正则表达式的某些问题变得复杂,可以毫无问题地处理

正则表达式只是树结构的压缩编码,类似于数学公式是描述算术的树结构的压缩编码。在每对相邻的字符之间,都有一个隐式follows操作符,它对应于一个具有两个子节点的节点,一个是其左侧的子节点,另一个是正则表达式的整个剩余部分;由|个字符分隔的子区域序列对应于一个alt节点,其子节点的数量与备选方案的数量相同,即比|个字符的数量多一个,而每个其他操作符只有一个子区域,即它操作的子区域,并且每个普通字符或字符类根本没有子节点。要计算匹配字符串的最大长度,您只需对该树结构进行自底向上的遍历,在每个节点贪婪地分配匹配该节点的最长字符串的长度,给定匹配其子节点的最长字符串的知识

确定与此树中任何给定节点匹配的最长字符串长度的规则如下:

followsx,y-xy:maxlenx+maxleny alta,b,…,z a | b |…| z:MaxLena,maxlenb,…,maxlenz maybex?:maxlenx repx*或posrepx+:无穷大 任何其他单个字符或字符类[…]:1 \1-style backreferences:对应括号表达式的maxlen 一个结果是,除非转义或字符类的一部分,否则任何地方都存在*或+显然会导致无限向上传播到树上,直到它到达根

例子 第二个例子:

Regex: (a|b|de)c?
"Function call" syntax: follows(alt(a, b, follows(d, e)), maybe(c))
As a tree:

     follows
     /     \
   alt     maybe
  / | \        \
 a  b follows   c
       /  \
      d    e
对于第二个正则表达式/树,自下而上的遍历将为叶节点a、b、d、e和c分配一个maxlen为1的值;然后,底部跟随节点的最大值为1+1=2;然后alt节点的maxlen为max1,1,2=2;可能节点的最大值为1;最顶层节点的maxlen为2+1=3,因此整个正则表达式的maxlen为2+1=3


如果您指的是允许其他Perl风格增强功能的正则表达式,那么它可能会变得更加复杂,因为局部最优的长度选择可能会导致全局次优的长度选择。我曾认为Perl风格的扩展甚至可能使正则表达式图灵完整,这意味着通常无法确定是否存在匹配的字符串-但似乎表明情况并非如此,除非在{…}构造中允许。

超出最简单的正则表达式,甚至很难找出哪些字符串可以匹配,更不用说最长的字符串了。你要的不是魔法,就是蛮力。这两个都不能解决问题。我怎么能猜-你猜是什么意思?@nnnnnn我的意思是如何确定或发现。抱歉,我刚刚更正了问题。是否将正则表达式转换为DFA?这显然不是一件小事。您想处理任何C或javascript正则表达式吗?如果你稍微限制一下可能性,那就容易多了。反向引用尤其令人讨厌。除了最简单的正则表达式之外,甚至很难找出哪些字符串可以匹配,更不用说最长的字符串了。你要的不是魔法,就是蛮力。这两个都不能解决问题。我怎么能猜-你猜是什么意思?@nnnnnn我的意思是如何确定或发现。抱歉,我刚刚更正了问题。是否将正则表达式转换为DFA?这显然不是一件小事。您想处理任何C或javascript正则表达式吗?如果你稍微限制一下可能性,那就容易多了。反向引用会特别烦人。这与正则表达式引擎在长度保证找不到匹配项时优化正则表达式以快速失败的初始分析相同。Java使用类似的分析来检查look-behind模式的长度,以拒绝inf.length模式,尽管它有一个长期存在的bug。无论如何,除了理论正则表达式的语法之外,没有可靠的方法来判断最长匹配字符串的长度。@nhahtdh:像我在这里所做的那样,通过确定最长可能的匹配来排除任何可能性。你有时可以通过做类似的计算来排除匹配,计算出最短的匹配。啊,是的,你是对的。可能的最长匹配仅用于分析后看模式。初始长度检查使用尽可能短的匹配。这与正则表达式引擎可能进行的初始分析相同,以优化正则表达式,使其在长度保证找不到匹配时快速失败。Java使用类似的分析来检查look-behind模式的长度,以拒绝inf.length模式,尽管它有一个长期存在的bug。无论如何,除了理论正则表达式的语法之外,没有可靠的方法来判断最长匹配字符串的长度。@nhahtdh:什么都不能确定
就像我在这里做的那样,通过确定尽可能长的比赛来排除。你有时可以通过做类似的计算来排除匹配,计算出最短的匹配。啊,是的,你是对的。可能的最长匹配仅用于分析后看模式。最短的匹配用于初始长度检查。