1700436321
1700436322
文件/usr/dict/web2列出了Webster’s Second International Dictionary[8](韦氏国际词典(第2版))收录的单词——234 936个单词,每行一个——单引号之间的神秘字符串是一个正则表达式,或谓模式。在本例中,它指定了只包含这7个字母的任意组合的行,而不包含其他内容。
1700436323
1700436324
结果得到了263个单词的惊人列表,如图4-4所示。我的母语是英语,但词表中有相当多单词我从未见过。无论如何,我把它们打印出来,寄给了那个家伙。我想他一定很满意,因为他没再找我。我体验了一次绝妙的经历,而且grep等工具和正则表达式之类概念的价值也被精彩地展示出来了。
1700436325
1700436326
1700436327
1700436328
1700436329
图4-4 试试在倒拿的计算器上显示以上单词
1700436330
1700436331
随着时间的推移,grep这个词被用作名词、动词和动名词(grepping),并成为Unix社区日常用语。你有没有在你的公寓里翻找(grep)过你的车钥匙?有些保险杠贴纸和 T 恤衫上写着“Reach out and grep someone”(伸手搜检他人),这是对AT&T广告语“reach out and touch someone[9]”(伸手触碰他人)的戏仿。
1700436332
1700436333
诺贝尔奖得主阿尔诺·彭齐亚斯是研究中心副总裁,高我三级。有一天他打电话问我,他想在公开演讲中使用这个短语,不知是否妥当。
1700436334
1700436335
1700436336
1700436337
1700436339
UNIX传奇:历史与回忆 4.6 正则表达式
1700436340
1700436341
前文写到“正则表达式”时,没有详细解释。正则表达式是一种用于指定文本模式的符号。它可以是单词,如expression;可以是短语,如regular expression;也可以是更复杂的文本。实际上,正则表达式就是一种描述文本模式的小型语言。单词或短语本身就是正则表达式,它在文本中代表自己,正则表达式识别器会找到它出现的每处地方。
1700436342
1700436343
正则表达式还可以通过赋予某些字符特殊含义来指定更复杂的模式,这些字符称为元字符(metacharacter)。例如,在使用grep时,元字符“.”匹配任意单个字符,而元字符“*”匹配前一个字符的任意数量的重复,因此模式“.*”匹配括号中的任意字符序列。
1700436344
1700436345
Unix对正则表达式的“痴恋”由来已久,正则表达式遍布于文本编辑器、grep及其衍生工具以及许多其他语言和工具中。正则表达式略加变形之后,也被用于文件名模式,如前文提到的匹配一组文件名的shell“通配符”。
1700436346
1700436347
肯·汤普森在Multics以及稍后GE 635(我第一次遇到正则表达式的地方)上的QED编辑器中采用了正则表达式。肯发明了一种非常快的算法,能够快速处理复杂的表达式。该算法还获得了专利。QED的功能足够强大,原则上可以只用编辑器命令编写任何程序(尽管没有哪个正常人会这样做)。我甚至写过一篇关于QED编程的教程,这事在很大程度上是白费力气,但从那以后我就开始写这类文档了。
1700436348
1700436349
对于大多数任务而言,QED都过于强悍了。肯和丹尼斯是Unix ed文本编辑器的原作者,后来又有几个人加以修改(甚至包括我)。ed比QED简单得多,但它也支持正则表达式。grep源自ed,所以它的正则表达式用法和ed中的一样。
1700436350
1700436351
文件名通配符使用正则表达式的变体风格。虽然通配符由shell解释,但由于PDP-7上的主存储器非常有限,所以最早的实现方式是由shell调用名为glob(代表“global”,意为“全局”)的独立程序。从模式中生成文件名扩展列表的操作被称为“globbing”。glob这个名字如今在Python等几种编程语言的库中仍然存在。
1700436352
1700436353
阿尔·阿霍对Unix的早期贡献之一是扩展了grep,让它能支持更丰富的正则表达式,例如可以搜索像this|that这样的替代模式。阿尔把这个程序称为egrep,表示“extended grep”(意为“扩展grep”)。
1700436354
1700436355
关于egrep,值得多说几句。它是理论结合实践的范例,也体现了 1127中心成员之间的典型互动,正是这些结合与互动成就了如此之好的软件。这个故事来自道格·麦基尔罗伊:
1700436356
1700436357
“在与霍普克罗夫特(Hopcroft)[10]及厄尔曼(Ullman)[11]合著的《计算机算法的设计与分析》(The Design and Analysis of Computer Algorithms)一书中,阿尔·阿霍为某个算法写了个例程,那正是egrep的第一个实现。我立即在一个日历程序里用上了。该程序使用自动生成的巨大正则表达式来识别五花八门的日期模式,如today、tomorrow、until the next business day等。
1700436358
1700436359
“令阿尔懊恼的是,识别器得花30秒左右的时间才能编译出来,运行起来反倒疾如闪电。
1700436360
1700436361
“他提出了一套绝妙的策略,即在需要用到时,才生成识别器,而不是预先全部生成。因此,虽然存在指数量级的状态,但每次只构造极少部分。这带来了巨大的变化:在实践中,无论处理多么复杂的模式,egrep总是跑得很快。egrep技术卓越,但除非你知道标准方法的性能有多差,否则就会视若无睹。”
1700436362
1700436363
这是个常见的Unix故事:来自真实用户的真实问题,对相关理论的深入了解,有效的工程使理论在实践中很好地发挥作用,以及不断改进。这一切都得益于团队中广泛的专业知识、开放的环境和尝试新想法的文化。
1700436364
1700436365
1700436366
1700436367
1700436369
UNIX传奇:历史与回忆 4.7 C语言
1700436370
[
上一页 ]
[ :1.700436321e+09 ]
[
下一页 ]