(转)为什么需要正则表达式 by 王珢

为什么需要正则表达式

by 王垠

学习Unix最开头,大家都学过正则表达式(regexp)。可是有没有人考虑过我们为什么需要正则表达式?

正则表达式本来的初衷是用来从无结构的字符串中提取信息,殊不知这正好是Unix的缺陷所在。Unix用无结构的字符串来表示数据,导致了诸多复杂的基于regexp的软件的诞生。sed, AWK, Perl, … 都是为了同样的目的来到这个世界上的。如果不是因为Unix用字符串来表示数据,我们就会拥有按数据结构类型的直接存储,而不需要折腾regexp。正则表达式有它自己的价值(针对自然语言),但是我们其实不需要把它应用到程序语言和操作系统里面。

正则表达式本身用一个字符串来表示,这带来另外一些问题。因为正则表达式的本质不是字符串,而是一个数据结构。学过计算理论的人可能知道这个数据结构叫做NFA(nondeterministic finite automaton,非确定性有限自动机)。所有的数据结构应该由程序语言本身来表示,就像用Java构造一个对象用 new ClassA("a") 一样。但是正则表达式强迫你把这个简单的构造函数调用写成一个字符串。所以在这个比方之下,你得写成new ClassA(\"a\")。这样当你想要组合这些表达式的时候就发现,正则表达式几乎都是不可组合(compose)的。你几乎不可能不能把两个regexp的变量A和B安全拼接成一个,比如用Java的字符串拼接A+B。因为你不知道这两个字符串拼在一起之后,那些稀奇古怪的符号会出现什么交叉反应,使得最后的识别的东西根本不是你想要的。

在正则表达式中,由于正则表达式本身的构造函数与数据本身合并到一起,我们不得不对某些“特殊字符”进行escape。这些特殊字符,其实是用来描述NFA的记号,它们属于更高一层的语言。可是在正则表达式里,它们与NFA节点里的字符混为一谈。比如很简单的一个block comment的正则表达式,却要写成这个样子:

/\\*([^\\*]|[^/])*\\*/

显然这样的表达式很容易出错。 如果我们用程序语言的表达式来构造这个表达式,它应该是这样:

(@... "/*" (@*(@!"*/")) "*/" )

在这个我自己设计的Scheme表达式里,以@开头的标识符都是构造函数。其中@...是构造sequence,@* 是构造一个zero-or-more的匹配,@!构造一个否定匹配。这个表达式是说:“以/ *开头,接着零个或者多个不是* /的字符,最后接着一个* /。这样一来清晰明了,什么表达式在什么“层次”都很清楚,不需要什么反斜杠escape,而且这样的表达式可以compose。比如:

(define reg1 (@... "/*" (@*(@!"*/")) "*/" ))
(define reg2 (@+ "foo"))
(define reg3 (@= "b"))

定义这三个表达式之后,我们之后可以用像(@... reg1 (@or reg2 reg3)) 这样的表达式来连接3个不同的表达式,构造出更大的表达式。这样的构造可以无限的扩展。从这里以及以往的经验,我总结出一个普遍适用的程序设计的教训:尽量不要把多个层次的语言“压缩”到一层。我们也看到正则表达式与“Unix哲学”有很大关系。我没有考古,所以不知道孰先孰后,但是它们肯定有直接的因果关系。两者都是Unix复杂性的来源。



This article was posted at yinwang’s sina blog,
on 2012-05-17.
Though it’s not available now.

时间: 2024-08-24 13:46:47

(转)为什么需要正则表达式 by 王珢的相关文章

(转)完全用GNU/Linux工作 by 王珢

完全用GNU/Linux工作 王珢 (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾,难以入睡.也希望看到这篇博文的朋友有所收获.) "UNIX 是简单的,你不需要成为天才也能理解这种简单" 由于GNU/Linux这个词太长,下面如果没有特别指明,“Linux”就是指“GNU/Linux”. 在这个年代,恐怕没有人需要我来介绍 Linux 是什么了吧?如果你觉得“Linux只不过是

(转)什么是“黑客” by 王珢

什么是“黑客” by 王垠很多程序员自豪的把自己叫做“黑客”(hacker),把编程叫做 hack.可是殊不知,其实在最高级的程序员眼里,“黑客”其实是一个贬义词.他们更愿意被叫做“程序员”(programmer),或者计算机科学家(computer scientist).当然,你有可能以一个 hack 从“世界一流大学”拿到一个 PhD.但是 PhD 其实不说明任何问题,世界上有太多的人拥有 PhD,其中绝大部分都是 hack.hack 的本质是不会变的——它是低级的工作. hack 的意思本

(转)小小科学家的归来 by 王珢

小小科学家的归来 by 王垠很多人来信关心我的现状,所以在写别的技术性文章之前,先说说我现在的情况吧.虽然自己追求的东西和经历都比较不同寻常,但是也许可以给奋斗中的人们一些慰藉和鼓励. 首先是超级好消息.几经周折,我得到了我想要的东西:异常强大而独立的思想.我成为了我想成为的人:曾经那个爱玩蚂蚁的“小小科学家”.他的灵魂回到了我身上.现在的我,每一天都充满了激情.脑子里总是有一些没法描述的,神奇的思想在萌发.它们让我感觉到无与伦比的美,让我的脸上浮现出笑容.它们让我从睡梦中蹦起,去试验.它们让我

(转)名称和本质 by王珢

名称和本质 by 王垠 我很喜欢 Richard Feynman 写的 <What Do You Care What Other People Think>.在最开头 Feynman 讲到他小时后的故事.他的父亲经常带他到外面散步,给他讲很多有趣的故事.他受到启发,后来成为了一名科学家.有一次,他们走到一个地方看见一只鸟.父亲说…… “See that bird? It’s a Spencer’s warbler. (I knew he didn’t know the real name.)

(转)对博士学位说永别 by 王珢

对博士学位说永别 by 王垠 经过深思熟虑之后,我决定再次“抛弃”我的博士学位.这是我第三次决定离开博士学位,也应该是最后一次了.这应该不是什么惊人的消息,因为我虽然读博士10年了,可是我的目标从来就不是博士学位.我在寻找更重要的东西,而且那个东西已经被我找到了.所以我的“博士生涯”其实完成了它的使命,基本上可以圆满结束了. 如果你从我之前的博文判定我现在生活在我所向往的环境中,那么你就误会了.虽然我学到了我想要的东西,但是却发现学术界不再是我向往的地方.相反,它阻碍了我的前进,让我很不开心.很

(转)我看PhD by 王珢

我看PhD by 王垠 前段时间看了一下这些关于 PhD 的负面信息: 一个专门反对读 PhD 的 BLOG 叫“100 Reasons NOT to Go to Graduate School”(下文简称“100个理由”) 哈佛大学教授 William James 的“The PhD Octopus”(写于 1903 年) 斯坦福大学的计算机系博士 Philip Guo 写的书“The Ph.D. Grind”(描述他的 PhD 生涯) 专门讽刺 PhD 生活的系列漫画“PhD Comics”

js正则表达式实例(汇总)

来源:如何用JAVASCRIPT 正则表达式取出字符串最后一组数字,谢谢  如  30CAC0040 取出40  3SFASDF92 取出92  正则如下://d+$/g   统一空格个数  来源:正则匹配空格的问题  字符串内字符键有空格,但是空格的数量可能不一致,通过正则将空格的个数统一变为一个.  例如:蓝色理想  变成:蓝色理想  aobert的正则:  <script>  var str="蓝色理想"  var reg=//s+/g  str = str.repl

关于正则表达式结果不一致

这个时间点本人还在学习正则表达式,不得不说遇到困惑的地方了. 下面就直接切入主题了,原本是想匹配百家姓的,为了快速看到效果,我使用了RegEx Tester测试工具,看看是否能匹配到 以下为百家姓的部分内容 赵Zhào:造父为周穆王驾车,穆王把赵城赐了给他,其后代以国为姓.赵匡胤是宋代的开国皇帝,据说赵姓放在第一位与此有关. 钱Qián:彭祖的孙子彭孚在西周朝廷中任钱府上士,其后人以其官为姓. 孙Sūn:周文王的一后代叫惠孙,他的后代以他的名字“孙”作为姓. 李Lǐ:皋陶的后人理征因得罪纣王被处

王垠:完全用Linux工作 - imsoft.cnblogs

完全用Linux工作,抛弃windows 我已经半年没有使用 Windows 的方式工作了.Linux 高效的完成了我所有的工作. GNU/Linux 不是每个人都想用的.如果你只需要处理一般的事务,打游戏,那么你不需要了解下面这些了. 我不是一个狂热的自由软件份子,虽然我很喜欢自由软件.这篇文章也不是用来推行自由软件运动的,虽然我觉得自由软件运动是非常好的. 这篇文章也不是用来比较 Linux 和 Windows 内核效率,文件系统,网络服务的.我现在是作为一个用户而不是一个开发者来说话的,我