我知道你在想什么 - "噢,天哪,认真,不再" - 但请耐心等待,我的问题不仅仅是标题.在开始之前,我保证永远不会尝试用正则表达式解析任意HTML,或者问别人怎么做.
这里解释为什么你不能这样做的所有许多答案都依赖于正则表达式的正式定义.它们解析常规语言,HTML是无上下文但不是常规的,所以你不能这样做.但我也听说过各种语言的许多正则表达式实现都不是严格规范的; 他们带来了超出正式正则表达范围的额外技巧.
由于我不知道任何特定实现的细节,例如perl,我的问题是:
tch*_*ist 13
您的问题的答案是肯定的,即所谓的"扩展正则表达式" - 它可能比正式意义上的正则表达式更恰当地称为模式 - 例如在Perl和PCRE中找到的那些确实能够递归下降解析上下文 -免费语法.
这篇文章的一对方法说明了将正则表达式应用于X/HTML并不是理论上的实际限制.在那里给出的第一种方法,即标记为天真的方法,更像是在大多数进行此类尝试的程序中易于找到的那种方法.这可以用于定义明确的非通用X/HTML,通常只需很少的努力.这是最好的应用程序,就像开放式X/HTML是最糟糕的.
标记为向导的第二种方法使用实际语法进行解析.因此,它与任何其他语法方法一样强大.然而,它也远远超出了绝大多数临时程序员的能力.它还有可能为了消极的利益重新创造一个完美的精细轮.我写这篇文章是为了展示可以做些什么,但实际上在任何情况下都不应该做.我想向人们展示为什么他们想要在开放式X/HTML上使用解析器,向他们展示即使使用当前可用的一些最强大的模式匹配工具,甚至接近正确也是如此艰难.
许多人误读了我的帖子,因为某种方式提倡与我实际说的相反.请不要搞错:我说它使用起来太复杂了.这是反例的证明.我曾希望通过展示如何使用正则表达式做到这一点,人们会意识到他们为什么不希望走这条道路.虽然一切皆有可能,但并非所有事情都是权宜之计.
我个人的经验法则是,如果所需的正则表达式只是第一类,我可能会使用它,但如果它需要对第二类的完全语法处理,我使用其他人已经编写的解析器.所以即使我可以编写一个解析器,我也没有理由这样做,而且还有很多不这样做.
当为了明确的目的精心设计时,模式可能比现成的解析器更容易受到格式错误的X/HTML的影响,特别是如果你没有真正的机会攻击所述解析器以使它们对常见故障更具弹性Web浏览器倾向于容忍的情况,但验证器不容忍.但是,我上面提供的语法模式只是为了格式良好但合理的通用HTML而设计的(尽管没有实体替换,很容易添加).解析器中的错误恢复完全是一个单独的问题,绝不是一个令人愉快的问题.
模式,特别是大多数人习惯看到和使用的更常见的非语法模式,更适合一次抓取一个离散的块,而不是用于生成完整的句法分析.换句话说,rexing通常比lexing更适合于解析. 如果没有语法正则表达式,则不应尝试解析语法.
但是不要太过分了.我当然不是故意暗示你应该立即转向一个完整的解析器只是因为你想要处理递归定义的东西.这种事情中最简单也许最常见的例子是检测嵌套项目的模式,如括号.对我来说,在我的代码中简单地填写这样简单的东西是很常见的,并且完成它:
# delete all nested parens
s/\((?:[^()]*+|(?0))*\)//g;
Run Code Online (Sandbox Code Playgroud)