首先,我不能做任何事情,只能参考我认为最有名的SO帖子:
RegEx match open tags except XHTML self-contained tags
现在,它甚至是StackOverflow的问题吗?我不知道,但我会试试......
我会从个人的角度说话。虽然我从来没有这样做,但我知道在我必须解析HTML的那一天,我肯定不会使用正则表达式;我将尝试找到一个HTML解析库。细
但我不知道为什么。
有一次,我决定用Java进行CSS验证。我知道“通过胆量”,正则表达式不会削减它,所以我使用了Parboiled。
我不知道为什么。
“为什么”让我烦恼。我根本不是正念法的新手。我只是不能在正则表达式引擎之间划清界限,也不能做到。
我的问题如下:这条线是什么?必须存在输入的基本特征,以便在数学上证明任何正则表达式引擎都无法可靠地确定成功和失败?
你能给出一个简单的理论输入,这个输入会使正则表达式引擎能够提供可靠的“匹配/不匹配”答案吗?如果是,这种输入的定义特征是什么?
编辑为了讨论这个问题,我将在SO上添加一个帖子建议的任务(我现在找不到链接,抱歉)这比HTML,但我不会使用正则表达式:shell命令行解析。
就shell而言,那些是等价的:
alias ll="ls -l"
alias ll=ls\ -l
alias l"l"=ls' -'l
"alia"s l"l= "ls\ -l
Shell引用机制非常多,我只会在这种情况下创建一个Parboiled语法...... 但这是“出于我的勇气”。因为我发现它可能更容易...... 但这并不能证明这对正则表达式来说是不可行的。
答案 0 :(得分:6)
正则表达式可以确定regular languages。但HTML不是常规语言。这是一个context-free language。无上下文语言是常规语言的超集。
基本上任何可以在其中包含递归元素的语言都不是常规的。常规语言必须“平坦”,因此不能嵌套。例如,在HTML中,一个<div>
可以嵌套在另一个中,并且它们可以嵌套的深度没有限制。正则表达式无法处理这种类型的通用嵌套。
答案 1 :(得分:3)
正则表达式主要是将给定模式与输入字符串匹配,看看是否成功。这是他们的首要目标。 RE库提供了其他功能,例如根据匹配获取输入字符串的子部分,但这仅适用于少数部分。如果您需要完整表示输入,则需要一个解析树。每个解析器都可以轻松地为您生成,因为这是他们的任务之一。使用RE,您也可以手动执行此操作。
如果要使用正则表达式,另一点是表达式的复杂性。很难测试错误,你大部分都得到了全部或全部,要么成功匹配(并得到你想要的信息),要么你什么也得不到,必须找到它的错误。使用解析器生成器,您可以交互式地构建语法以获取越来越多的信息,更不用说您可能已经找到了每个相关解析器的HTML语法。
最后,不要忘记无效输入的反馈。有RE,你什么也得不到。使用解析器,您会收到错误消息,指出您遇到的实际问题。一些解析器(如ANTLR生成的解析器)甚至可以处理简单的语法错误,并且仍为您生成可用的解析树。
答案 2 :(得分:1)
你说你听说正则表达式无法解析HTML。这是误导性的:术语含糊不清。
最初,“正则表达式”一词具有特定的数学意义。当然,编程语言发明了正则表达式引擎。但随着时间的推移,这些引擎的功能增强(反向引用,外观,递归模式......)。原始的“常规语言”是正则表达式引擎可识别的唯一语言,这已经不再适用了。
例如,/^(a*)b\1$/
可识别字符串b
,aba
,aabaa
,aaabaaa
等;这不是常规语言。
我认为如果你真的想要,可以编写一个正则表达式来测试HTML有效性。 (你没有。)在实践中,无论你使用什么语言都会有一个库,但正如你的使用情况一样,正则表达可能更容易。
答案 3 :(得分:0)
我认为你能得到的最好答案就是古老的格言:“当你拥有的只是一把锤子时,整个世界看起来像钉子。”正则表达式几乎可以做任何事情。他们的能力在于能够使用任何字符串。但是,仅仅因为你可以使用某些东西并不意味着你应该。正则表达式很慢,而且效率很低(你可以以多种方式优化它们,但很少有人知道这些技术,实际上花费更少的时间实现它们并彻底测试和检查它们的正则表达式)。
对于HTML,有更好的工具。比正则表达式更快并且更适合使用HTML(能够构建节点树等)的工具。并不是说你不应该使用正则表达式来解析HTML,而是有一个更好的工具。当你可以使用链锯时,为什么还要尝试用黄油刀看树?