在没有关于解析(X)HTML或XML并且询问正则表达式的问题的情况下,SO上没有任何日子.
虽然相对容易想出用于演示此任务的正则表达式的不可行性的示例或用表达概念的表达式集合,我仍然无法在SO上找到为什么在外行人中无法做到这一点的正式解释条款.
到目前为止我在这个网站上找到的唯一正式解释可能非常准确,但对于自学成才的程序员来说也很神秘:
这里的缺陷是HTML是Chomsky Type 2语法(无上下文语法)而RegEx是Chomsky Type 3语法(正则表达式)
要么:
正则表达式只能匹配常规语言,但HTML是无上下文的语言.
要么:
有限自动机(它是正则表达式下面的数据结构)除了它所处的状态之外没有内存,如果你有任意深度的嵌套,你需要一个任意大的自动机,它与有限自动机的概念相冲突.
要么:
常规语言的Pumping引理是你不能这样做的原因.
[公平地说:以上大多数解释链接到维基百科页面,但这些并不比答案本身更容易理解].
所以我的问题是:有人可以提供一个外行人的上述正式解释的翻译,为什么不可能使用正则表达式来解析(X)HTML/XML?
编辑:在读完第一个答案之后,我认为我应该澄清:我正在寻找一个"翻译",它也简要地解释了它试图翻译的概念:在答案的最后,读者应该有一个粗略的想法 - 例如 - "常规语言"和"无语境语法"是什么意思......
我正在尝试创建一个.NET RegEx表达式,它将正确地平衡我的括号.我有以下RegEx表达式:
func([a-zA-Z_][a-zA-Z0-9_]*)\(.*\)
Run Code Online (Sandbox Code Playgroud)
我想要匹配的字符串是这样的:
"test -> funcPow((3),2) * (9+1)"
Run Code Online (Sandbox Code Playgroud)
应该发生什么是正则表达式应该匹配从funcPow第二个右括号到第二个右括号.它应该在第二个右括号后停止.相反,它一直匹配到最后一个右括号.RegEx将返回此:
"funcPow((3),2) * (9+1)"
Run Code Online (Sandbox Code Playgroud)
它应该返回:
"funcPow((3),2)"
Run Code Online (Sandbox Code Playgroud)
任何有关这方面的帮助将不胜感激.
PCRE具有称为递归模式的功能,可用于匹配嵌套的子组.例如,考虑"语法"
Q -> \w | '[' A ';' Q* ','? Q* ']' | '<' A '>'
A -> (Q | ',')*
// to match ^A$.
Run Code Online (Sandbox Code Playgroud)
它可以在具有模式的PCRE中完成
^((?:,|(\w|\[(?1);(?2)*,?(?2)*\]|<(?1)>))*)$
Run Code Online (Sandbox Code Playgroud)
(示例测试用例:http://www.ideone.com/L4lHE)
abcdefg abc,def,ghi abc,,,def ,,,,,, [abc;] [a,bc;] sss[abc;d] as[abc;d,e] [abc;d,e][fgh;j,k]
<abc> [<a>b;<c,d>,<e,f>] <a,b,c> <a,bb,c> <,,,> <> <><> <>,<> a<<<<>>><a>> <<<<<>>>><><<<>>>>
<z>[a;b] <z[a;b]> [[;];] [,;,] [;[;]] [<[;]>;<[;][;,<[;,]>]>]
<a bc> <abc<de> [a<b;c>;d,e] [a] <<<<<>>>><><<<>>>>> <<<<<>>>><><<<>>> [abc;def;] [[;],] [;,,] [abc;d,e,f]
[<[;]>;<[;][;,<[;,]>]]> <z[a;b>]
.NET中没有递归模式.相反,它为基于堆栈的操作提供了平衡组,以匹配简单的嵌套模式.
是否可以将上述PCRE模式转换为.NET Regex风格?
(是的,我知道最好不要使用正则表达式.这只是一个理论问题.)