当前位置:  开发笔记 > 编程语言 > 正文

何时问题对于正则表达式来说过于复杂?

如何解决《何时问题对于正则表达式来说过于复杂?》经验,为你挑选了5个好方法。

请不要回答明显的问题,但有哪些限制标志告诉我们使用正则表达式不能解决问题?

例如:为什么正则表达式的完整电子邮件验证过于复杂?



1> Daniel Spiew..:

正则表达式是有限状态自动机的文本表示.也就是说,它们仅限于非递归匹配.这意味着您的正则表达式中不能包含"范围"或"子匹配"的任何概念.请考虑以下问题:

(())()

所有开放的parens都与一个紧密的paren相匹配吗?

显然,当我们将此视为人类时,我们可以很容易地看到答案是肯定的.但是,没有正则表达式能够可靠地回答这个问题.为了进行这种处理,您需要一个完整的下推自动机(如带有堆栈的DFA).这最常见于解析器的幌子,例如由ANTLR或Bison生成的解析器.



2> Jeff Atwood..:

需要注意的一些事项:

    开始和结束标记检测 - 匹配配对

    递归

    需要倒退(虽然你可以扭转字符串,但这是一个黑客)

正如我所爱的那样,正则表达并不擅长这三件事.请记住,保持简单!如果你正在尝试构建一个"一切"的正则表达式,那么你可能做错了.



3> Adam Rosenfi..:

当您需要解析未由常规语言定义的表达式时.


SO无可救药地偏向于极简主义,几乎无用的答案.

4> mmcdole..:

它归结为使用常识.如果你想要匹配的东西变成了一个无法管理的怪物正则表达式,那么你需要将它分解成小的,逻辑的正则表达式,或者你需要开始重新思考你的解决方案.

获取电子邮件地址(根据您的示例).这个简单的正则表达式(取自RegEx buddy)匹配99%的所有电子邮件:

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

它很简短,你很少会遇到问题.但是,正如RegEx buddy的作者指出的那样,如果您的电子邮件地址位于罕见的顶级域名".museum"中,则不会被接受.

要真正匹配所有电子邮件地址,您需要遵守RFC 2822标准.它概述了电子邮件地址可以格式化的多种方式,而且非常复杂.

以下是尝试遵守RFC 2822的示例正则表达式:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x
0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]
(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)
{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08
\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

这显然成为收益递减的问题.最好使用容易维护的实现,该实现匹配99%的电子邮件地址,而不是接受99.9%的电子邮件地址的怪物.

正则表达式是程序员工具箱中的一个很好的工具,但它们不是解决所有解析问题的方法.如果您发现RegEx解决方案开始变得非常复杂,您需要尝试将其逻辑分解为较小的正则表达式以匹配部分文本,或者您需要开始查看其他方法来解决您的问题.同样地,正则表达式由于其性质而无法解决(正如一张海报所说,不遵守常规语言).



5> Jan Goyvaert..:

正则表达式适用于标记,查找或识别单个文本位,例如在源代码中查找关键字,字符串,注释等.

正则表达式不适用于确定多个文本位之间的关系,例如,使用正确配对的大括号查找源代码块.你需要一个解析器.解析器可以使用正则表达式来标记输入,而解析器本身则确定不同的正则表达式匹配如何组合在一起.

基本上,如果您开始考虑"平衡组"(.NET的捕获组减法功能)或"递归"(Perl 5.10和PCRE),那么您将使用正则表达式.

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有