有一个类似的问题,但它只是得到了人们总是给出的关于正则表达式语法的旧答案,但这不是重点,所以请尽量不要扯下关于正则表达式语法的旧答案。这一次尝试更具原创性和个性化。
正则表达式语法非常紧凑,几乎太紧凑而不好。它就像代码打高尔夫, 每个人都同意代码打高尔夫球在生产代码中不是一件好事。然而,大多数人接受正则表达式语法,这似乎......至少可以说是矛盾的。
所以现在可能会听到一些常见的防御措施包括:
回答:紧凑
计数器:在这个时代,我们是否都同意代码应该识字并且像“客户端”这样的变量优于“c”?
< / LI>回答:这是一种“域专用语言”
计数器:所有非常容易理解的,非紧凑的,非神秘的,我敢说那些像SQL或LINQ那样漂亮的域语言怎么样?
答案:一旦你知道它就很容易理解。
计数器:即使您以前从未使用过,大多数优秀的语言都很容易理解。例如,任何人都可以很容易地跳入Python,即使他们以前从未见过它。为什么人们在用这么难看的语言来捍卫正则表达式,然后再继续抱怨Lisps括号?
好的,现在每个人都试图在这里做到原创和诚实,不要只是拉出20年前使用的程序员设计正则表达式的旧的死记硬背答案。除非你真的相信它们在这个时代是有效的命题。
编辑:为了记录,我知道多年前的Regex,即使在今天也经常使用它们,甚至可能会让它们搞砸。然而,我突然有一种感觉,也许是时候重新考虑我所采取的关于正则表达的“真理”的事情,并从现代的角度来看待它们。主要是因为提问原则对于进一步发展是必要的,并且因为很多新人对他们抱怨很厉害,他们不能正确地说出来,所以我决定尝试进入一个新人的角度并考虑一些好处反对正则表达式。
至于主观,我认为这不是主观的,也不是那些日常事务的程序员笑话的程序员。相反,它与程序员有关。
至于议论,这就是问题的关键。为了获得良好的论证pro和con regex过时的语法,这可以让新手真正了解为什么正则表达式是他们的,甚至更好的希望得到一些新人来提出一个更好的解决方案美国老头脑看不到因为我们被正则表达式的“冷静”所蒙蔽。
引用:
Perl 5.10文档 正则表达式融化成一堆 难以理解的因为这么多的滑稽 功能已经渗透到语法中 没有人可以写出明智的 它的文档。
你想说正则表达式已经变得无法维护了吗?那么作为优秀的程序员,我们应该考虑重构它们吗?也许我们已经完成了许多其他技术的清理和尝试?
答案 0 :(得分:34)
我要说的大部分内容都是由Adam和DGM解决的,但我认为它们不能很好地涵盖你的第二点。
“所有非常容易理解的,非紧凑的,非神秘的,我敢说那些像SQL或LINQ那样漂亮的域语言怎么样?”
我认为一个表达答案的好方法是问,你如何使用英语来解释正则表达式?
<TAG\b[^>]*>(.*?)</TAG>
查找“&lt; TAG”字边界为零或更多不是'&gt;'的字然后是'&gt;'记住零个或多个东西,停在第一个“&lt; / TAG&gt;”
这是一个相当简单的正则表达式。英文表格真的更容易理解吗?你能做得更好吗?
正则表达式很难阅读,但你想从中得到的东西也很难解释。
答案 1 :(得分:26)
请看问题的另一面:如何设计一种新的语法,将所有功能,一致性,简洁性和健壮性体现为正则表达式,但是程序员更友好?
答案 2 :(得分:17)
你的反驳论据似是而非。你知道正则表达式的语法,还是你从无知的角度进行争论?建立你的偏见是一个重要的观点。
这根本不像打高尔夫球。我不确定你的关系。为什么不使用相同的参数来抱怨指针或其他东西呢?
正则表达式的紧凑性与不良变量名称无关。名为c的变量可以是任何东西。正则表达式语法既不模糊也不含糊。它完全描述了它的模式。
这是一个DSL。那怎么回事?你有没有试过在SQL中做复杂的事情?这也是一个很大的混乱。做同样的事情需要更多的打字和更多的语法并不能改善这种情况。我教的大多数人都有正则表达式的问题,因为他们不习惯于思考和设计模式,而不是因为语法是异国情调。
一旦你知道它就很容易理解。嗯,确实如此。电动工具并未针对新手或不愿意学习的人进行优化。我不抱怨Lisp括号,但我不介意正则表达式语法。
如果您不想使用正则表达式,那么请不要。使用字符串操作函数或解析器。使用其他一些工具。当你忙着这件事的时候,我将面临十大问题,因为我不会逆潮流,也不会把工具归咎于我无法完成的工作。
取决于你想完成多少工作。找到最快到达那里的工具并学习它。如果你不喜欢这样,那就发明一些更好的东西。在那之前,停止抱怨。
答案 3 :(得分:15)
这实际上是美国退休程序员协会(American Association of Retired Programmers)对今天抨击Python和Java的年轻鞭挞者的阴谋。我们需要保持对神秘主义者的敬畏和敬意,他们的聪明才智克服了微小的核心记忆和具有3个字符助记符的神秘语言的挑战......并且喜欢它。上坡......两种方式......在雪地里。 : - )
答案 4 :(得分:11)
我会捍卫正则表达式语法,因为它(粗略地)匹配我在学习算法时所学到的符号。机器课程。这是一种生成机器来摄取指定常规语言的简便方法。
正则表达式的语法就是这样,因为它真的是你需要完全描述你正在寻找的行为。
答案 5 :(得分:9)
它有效!!
如果有一种易于阅读的语言,在每种主要的编程语言中都有扩展,并且有很好的文档和测试,而不是像正则表达式那样压缩,但是既不太冗长(冗长=烦人),我想更多地了解它< / p>
答案 6 :(得分:8)
正则表达式的一些问题不是语言本身,而是人们试图使用它们。当他们真正想要的是一个相当简单的解析器时,他们将编写正则表达式的行和行。
正则表达式适用于简单到中等复杂的子字符串匹配和数据提取。但是在复杂的某些方面,你只需要编译编译器并编写一个真正的解析器。我想很多人都没有意识到正则表达式主要用于匹配,而不是用于解析。
答案 7 :(得分:6)
您应该将正则表达式视为高端电动工具(我的意思是建筑行业意义上的电动工具)。
如果你要为你的棚子建一个小工作台,你就不要拔出钉枪,电锯和工业路由器。你使用锯子,钉子和锤子。
同样地,你不会在那里建造一座没有起重机的30层建筑。
我们的想法是使用正确的工具 AND 为您的技能水平提供合适的工具。
如果您必须砍伐一棵树,请确保在启动电锯之前了解所有关于回扣的信息。如果你不这样做,那就用手锯代替自己去医院,重新连接断肢。
我使用正则表达式的方式我使用电锯 - 非常小心。如果您对该工具不舒服,请不要使用它。一旦你学会了如何正确使用它,你会发现更快地完成工作要容易得多。
答案 8 :(得分:6)
正则表达式的另一个问题是它有很多种风格。 .Net正则表达式与php正则表达式与其他正则表达式相比,所有看起来都相似,但不会给出相同的结果(有时根本没有结果)。
答案 9 :(得分:6)
其他人已暗示这一点,但明确指出:
常规语言与编程语言不同。他们更接近数学符号。
紧凑性和怪癖更多的是试图强制使用ASCII字符的精确符号,而不是故意尝试简洁或混淆。
答案 10 :(得分:5)
我认为类似SQL的正则表达式语言将是一个引人入胜的项目。我很乐意看到有人创造这个。
为什么不有一种语言可以写
LOOK FOR "<TAG"
THEN WORDBOUNDARY THEN ZERO-OR-MORE NOT('>') FOLLOWED-BY '>'
THEN ZERO-OR-MORE SOMETHING REMEMBERED
THEN NEAREST "</TAG>"
我不确定目标受众是谁 - 我不认为我会使用它,因为我一直都在学习正则表达式。
当然,那些需要使用复杂的表达方式的那些人几乎映射到那些必须处理复杂事物并且日常工作更多的程序员?
答案 11 :(得分:5)
Pyparsing(http://pyparsing.wikispaces.com/Examples)是一个Python库,可以很容易地编写高度可读的类似于regex的表达式,就像这些将解析“Hello,World!”的行一样:
from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!"
greet.parseString("Hello, World!")
看起来这个库非常接近能够匹配正则表达式的强大功能(参见上面提到的示例页面)。
答案 12 :(得分:4)
类似于BNF符号等,是许多良好语言规范的基础。所以有意义的是,这样的符号将在词法分析器中用于指示预期字符的类。基本符号真的不是那么神秘。
然后我认为有一个UNIX-do-you-you-you-can-in-a-single-line的想法接管了。在sed和grep脚本改进之后,正则表达式获得了新的权力,但是它们的缩写表示。 Larry Wall将它们作为解析文本的通用工具整合到Perl中。我猜它对于仍然对perl很重要的oneliner保持了紧凑性。并且有常见字符类的简写名称,甚至更多的权力被要求并给予正则表达式。当然,由于Perl也是模块的语言,因此正则表达式语法也可以在语句块中使用,并且它利用了更广为人知的语法。
他们加入Java实际上是让人们看到他们的东西,IMO。 Java没有做任何事情来容纳它们。结果,具有中等难度的反斜杠的表达变成密集的反斜杠丛林。如果你愿意,Java给正则表达式一个新的市场,但它是最糟糕的形式。如果你已经看过那些,并且没有得到更多的关注,你可能会认为正则表达式是一个不应该的东西。
有趣的是,给定一个足够清晰的语法,对于Ambrose的详细版本,有人可以为Perl提出一个模块,可以使用详细的正则表达式并将其“编译”为Perl理解的紧凑正则表达式,使用更简单的正则表达式{ {1}}或可能是overload::constants
语法。
答案 13 :(得分:3)
这是它的方式......主要是出于传统原因,正如你正确指出的那样。现在
就我个人而言,我发现regexps(至少是常规任务所需的部分)很容易拿起..一天或2.高级的东西很难(MasteringRegExp书的后半部分)但是你不经常需要它任
答案 14 :(得分:3)
回顾你提到的类似问题及其答案,我看到了一些创造“友好”替代语法的尝试,这些语法来自我们今天所知道的正则表达的支持者和批评者。
我发现它们的可读性比同等的正则表达式更低。
现在,被授予,我是正则表达式的常规用户,因此我确信我对他们的安慰是其中的重要部分。但我对他们的主要问题并不是陌生,而是他们很快就变得太大而无法立即接受。当你的20个字符的正则表达式成为一个10行×30列的伪英语表达时,它变得更加难以看出它的各个部分是如何相互关联的。
也许有人会想出一种替代语法,这种语法普遍具有更高的可读性,即使在复杂的情况下也是如此,但我认为这样的语法本质上需要一些等同于子程序的调用。我们不会用15层嵌套逻辑编写200行应用程序代码块,因为它只是为了跟踪它的逻辑而不是一个巨大的任务,更不用说弄清楚它实际上做了什么。如果我们要将正则表达式分解为更像英语的形式,那么同样的问题就会发生,我们需要相同的工具来管理它。
答案 15 :(得分:3)
正则表达式(至少最初)描述了常规语言。常规语言具有非常好的理论属性,因为它们都可以用确定性有限自动机来描述和描述。用于非平凡正则表达式的DFA对于手动编码很痛苦。
更重要的是,在perl的后端使用的正则表达式编译器等都非常擅长。手动调整具有竞争力的代码是非常困难的。
最后,它们的存在主要是历史文物。他们已经有很长一段时间了,大家都知道了。您拥有的工具和其他人可以支持的工具比尚不存在的理论工具要好得多。
如果它只是让你失望的语法,也许你应该考虑在Haskell中查看解析器组合器。他们可以表达相同想法的超集,并具有更明确的语法。
答案 16 :(得分:2)
就像亚当说的,有什么更好的吗?我不禁想到尝试做一堆strcmp操作而不是一个好的正则表达式。像任何富有表现力的语言一样,有可能滥用正则表达式并制作非常难以理解的结构,但是通常即使看似不可读的正则表达式也比等效的程序代码更有意义。
如果没有正则表达式,您必须编写自己的例程来解析,回溯,比较,存储索引,进行替换以及管理所有结果。正则表达式以非常富有表现力的形式为您提供所有这些。我不喜欢重复代码,但如果每次我需要寻找一个中等复杂的模式时我必须编写自己的解析器...我不知道我会做什么。
是的,正则表达式有不同的风格,但大多数最流行的正则表达式非常相似,而且您使用它们的任何语言通常都有文档来帮助您阅读它。
答案 17 :(得分:1)
来自perl模块Regexp::English:
Regexp :: English提供了一种备用的正则表达式语法,比标准机制稍微冗长一点。此外,它还增加了一些方便的功能,如增量表达式构建和绑定捕获。
use Regexp::English;
my $re = Regexp::English
-> start_of_line
-> literal('Flippers')
-> literal(':')
-> optional
-> whitespace_char
-> end
-> remember
-> multiple
-> digit;
while (<INPUT>) {
if (my $match = $re->match($_)) {
print "$match\n";
}
}
答案 18 :(得分:0)
我敢打赌,本次讨论中的所有参与者都同意,对于某些小正则表达式代码,人们必须用英文写一段长段来描述它的作用。任何类型的语言都可以用于执行甚至最简单的正则表达式所描述的语言,可能会使用N行代码执行此操作,其中N(可能)与正则表达式本身的长度相比呈指数增长。