注1:本文是整理性文章不是记录性文章(13.4.20 plan——13.7.20 begin——13.7.22 done)

注2:第二遍写了,第一次写的时候,本文的雏形已经有了,并且已经写到第二节了。然后因为其他事情需要系统挂起,就点了ubuntu右上角的快速启动,谁知点到了注销,它和挂起挨得那么近!更何况我是用触摸板操作的。当系统让我登录的时候我才反应过来。于是赶快开机看看made中的文章保留下来没有。你猜到了,made没有保留。我试了,若是挂起/关机时,made能够保留下来。教训一:made每次结束/暂停编辑时都要export;教训二:我在linux中关机/重启/挂起/注销操作再也不用鼠标执行了,改用终端,或者直接合上笔记本盖子。

0 写在前面

前段时间,为了处理大量的文字信息,找了并使用了不少小软件,主要是用它们内部的正则(可以看这篇文章)。当然,也包括一些编辑器。根据我掌握的一些正则,写出了一些查找规则,但是在这些软件上应用的时候,发现无法识别。我原以为是我的表达式写错了,后来发现不是,因为有几个软件能够识别出来。当时,我就郁闷,这正则难道有不同的版本?不同的软件支持的是不同的版本?接着,就想着好好整理一下,让自己对正则有个完整的认识。最终想达到的目标: 能够了解常用的软件/语言对正则的支持情况 (恐怕达不到,完善文章时加的删除线);能够掌握一套通用的正则语法(包括它的高级形式),同时希望它能够应用到所有地方;能够整理总结出一套正则式子在php编程中使用。(当时,就萌生了这个想法,但是一直没有落实,如今才写出来,惭愧惭愧呀!)

本文主要介绍正则,至于正则的语法以及例子分析,我会放到后续的几篇关于正则表达式的文章中。

1 正则的来龙去脉

1940年,Warren McCulloch与Walter Pitts将神经系统中的神经元描述成小而简单的自动控制元。 1950年代,数学家斯蒂芬·科尔·克莱尼利用称之为“正则集合”的数学符号来描述此模型。肯·汤普逊将此符号系统引入编辑器QED,然后是Unix上的编辑器ed,并最终引入grep。自此,正则表达式被广泛地使用于各种Unix或者类似Unix的工具,例如Perl。 Perl的正则表达式源自于Henry Spencer写的regex,它已经演化成了pcre(Perl兼容正则表达式,Perl Compatible Regular Expressions),一个由Philip Hazel开发的,为很多现代工具所使用的库。————本段摘自维基百科

在最近的六十年中,正则表达式逐渐从模糊而深奥的数学概念,发展成为在计算机各类工具和软件包应用中的主要功能。不仅仅众多UNIX工具支持正则表达式,近二十年来,在WINDOW的阵营下,正则表达式的思想和应用在大部分 Windows 开发者工具包中得到支持和嵌入应用!从正则式在Microsoft Visual Basic 6 或 Microsoft VBScript到.NET Framework中的探索和发展,WINDOWS系列产品对正则表达式的支持发展到无与伦比的高度,几乎所有 Microsoft 开发者和所有.NET语言都可以使用正则表达式。如果你是一位接触计算机语言的工作者,那么你会在主流操作系统(*nix[Linux, Unix等]、Windows、HP、BeOS等)、主流的开发语言(PHP、C#、Java、C++、VB、Javascript、Ruby以及python等)、数以亿万计的各种应用软件中,都可以看到正则表达式优美的舞姿。————本段摘自百度百科

正则不是语言,不是程序,甚至不是技术,它仅仅是一种技巧,但它确实十分强大。下面我们就从它的根源(底层?)了解。

2 正则的引擎

在给这小节命名的时候,我不知该用哪个词。因为网上对正则的分法的用词不尽相同(难道是基于不同的划分标准么?),在风格、语法、形式、引擎这几个词语之间我最后选择了“引擎”,貌似更贴切一点,听起来也更专业一点(哈哈)。

正则引擎主要可以分为基本不同的两大类:一种是DFA(确定有限自动机(Deterministic Finite Automaton)),另一种是NFA(非确定有限自动机(Nondeterministic Finite Automaton))(关于DFA、NFA可以查看更多)。DFA和NFA都有很长的历史,但NFA的历史更长一些。(自动机?伟大的数学知识,详见维基百科)

部分程序以及所使用的引擎:

  1. DFA: awk(大多数版本)、egrep(大多数版本)、flex、lex、MySQL、Procmail
  2. 传统型NFA: GNU Emacs、Java、grep(大多数版本)、less、more、.NET语言、PCRE library、Perl、PHP(所有三套正则库)、Python、Ruby、sed(大多数版本)、vi
  3. POSIX NFA: mawk、Mortice Kern Systems’ utilities、GNU Emacs (明确指定时使用)
  4. DFA/NFA混合: GNU awk、GNU grep/egrep、Tcl.(对于混合引擎,系统会根据任务的不同选择合适的引擎)

NFA和DFA都发展了二十多年,产生了许多不必要的变体,结果,现在的情况比较复杂。POSIX标准的出台,就是为了规范这种现象。DFA显然已经符合新的标准,但是NFA风格的结果却与此不一,所以NFA需要修改才能符合标准。这样一来,正则引擎可以粗略地分为3类:DFA(符合或不符合POSIX标准的都属此类)、传统型NFA、POSIX NFA。

某些情况下,DFA与POSIX NFA的区别是很明显的。DFA不支持捕获型括号(capturing parentheses)和回溯(backreferences)。关于这三者的更多区别请参考链接1链接2和它提到的书这本书

而现在,我想把它们归类。1:上述三种引擎;2:还有三种标准(BRE(基本正则表达式Basic Regular Expression)、ERE(扩展正则表达式extended regular expression) 和 ARE(高级正则表达式Advanced regular expression)。其中 BER 和 ERE 属于 POSIX 标准,ARE 则是由各家定义的扩展);3:还有两种风格:Perl、POSIX。

我曾试着将DFA、NFA、POSIX、BRE、ERE、ARE、perl、PCRE在一个思维导图中体现出它们之间的关系,但在网上找资料找了好久甚至已经画出了几项到最后还是放弃了,因为自己认识太粗浅的原因,我实在找不到头绪。那我接下来就分开讲吧,先讲一讲这3种标准。

3 正则的标准(2种?3种?)

传统上,POSIX标准定义了两种正则表达式语法, 即:BRE 和 ERE。ERE 修改了 BRE 中的部分语法,并增加了一些语法符号。同时,ERE 取消了子表达式 “()” 和 次数匹配 “{m,n}” 语法符号的转义符引用语法,在使用这两种语法符号时,不在需要添加转义符。 与此同时, ERE 也取消了非正则语义的子表达式向前引用能力。BRE 和 ERE 共享同样的 POSIX 字符类定义。更多BRE和ERE区别可以看这篇文章

除了 POSIX BRE 和 ERE 之外,libutilitis 还支持与TCL 8.2兼容的高级正则表达式语法(ARE)。 通过为 stRegEx 参数增加前缀 “***:” 就可以开启 ARE 模式,这个前缀覆盖 bExtended 选项。基本上讲,ARE 是 ERE 的超集。 它在 ERE 的基础上进行了如下几项扩展:

  1. 支持”懒惰匹配”;
  2. 支持子表达式的向前引用匹配;
  3. 无名子表达式;
  4. 向前预判;
  5. 支持模式切换前缀;
  6. 与 BRE/ERE 模式不同的 Perl 风格字符类换码序列;

关于这种分法的标准的更多信息可以查看这篇文章

4 通常说的2种风格
  1. POSIX风格:Regular Expression。这里有简单介绍,可以参考。
  2. Perl风格:Perl-Compatible Regular Expression(包括PCRE)。举Perl语言的正则语法,其实还有PCRE的

我蛮喜欢 Perl 中的“替换”、“转化”模式的,能把替换规则直接写到正则中,只可惜 php 中没有,常见的软件中也没有。后来分析自己的需求,只是想在替换时,能够在新的内容中引用原来文本中的字符。其实,不用“替换”模式也能办到的,在我见识了一些正则实例后才发现,在替换时,可以通过一些$1,$2,$3的形式来引用子字符串(通用么?待考究)。

5 .net的正则历史

怎么突然出来个 .net 正则的历史?在查阅正则时,发现了.net正则,就觉得有必要也了解了解。下面是引用,也算是正文:

尽管数十年来很多 UNIX 工具都支持正则表达式,但仅仅是近十年来,它才在大部分 Windows 开发者工具包中得到体现。在 Microsoft Visual Basic 6 或 Microsoft VBScript 中,即使情况理想,正则表达式仍难以使用。但随着.NET Framework 的推行,正则表达式的支持发展到极点,所有 Microsoft 开发者和所有 .NET 语言都可以使用正则表达式。

我直接从msdn中查正则说明,从msdn中也没有也没有找到asp.net正则的风格/标准/引擎,我给出的链接中只说出了语法与用法而已。

本小节没有让我更多的了解正则,只仅仅是多了一个介绍asp.net的正则语法的链接罢了。

6 本文参考链接及文章

您可能在前面已经看到过了:

  1. Perl 中的正则表达式
  2. 正则表达式说明
  3. POSIX RE规格简述
  4. 正则表达式历史和风格
  5. dfa与nfa
  6. 正则表达式-维基百科
  7. 正则表达式-百度百科
  8. 正则引擎的分类
  9. 精通正则表达式_NFA、DFA和POSIX
  10. LINUX正则表达式特性及BRE与ERE的区别
  11. ASP.NET 中的正则表达式
  12. 自动机
  13. 《精通正则表达式》(第三版)


blog comments powered by Disqus

Published

22 July 2013

Tags