正则表达式 – POSIX & PCRE

前言

正则表达式在我们日常的软件开发过程中被广泛使用,例如编写Nginx配置文件、在 Linux与macOS下查找文件,然而不同软件不同操作系统对于正则的应用有着不一样的行为,主要原因是正则表达式演进过程中,出现POSIX与PCRE派系之分。


一、历史

先了解一下正则表达式的演进史

20世纪40年代,两位神经生理学家Warren McCulloch 和Walter Pitts,研究出了一种用数学方式来描述神经网络的方法,可以将神经系统中的神经元描述成小而简单的自动控制元。

50年代,一位叫Stephen Kleene的数学家在McCulloch和Pitts早期工作的基础上,发表了《神经网络事件表示法和有穷自动机》 论文。这篇论文描述了一种叫做 “正则集合(Regular Sets)” 的数学符号,引入了正则表达式的概念。

60年代,Unix之父Ken Thompson发表了《正则表达式搜索算法》论文。并且根据这篇论文的算法,将正则引入到编辑器qed,以及之后的编辑器ed中,然后又移植到了我们熟悉的文本搜索工具grep中。

70年代,由于grep支持的功能不多,因此Alfred Aho编写了egrep程序(其中e表示加强版的意思)。在grep 、egrep 发展的同时,awk 、lex 、sed等异军也开始凸起,每个程序所支持的正则表达式都有差别。

80年代,POSIX (Portable Operating System Interface) 标准公诸于世,它制定了不同的操作系统都需要遵守的一套规则,其中就包括正则表达式的规则。遵循POSIX规则的正则表达式,称为POSIX派系的正则表达式。Unix 系统或类Unix系统上的大部分工具,如grep 、sed 、awk等都属于POSIX派系。

同样在80年代,Larry Wall发布了Perl编程语言,其中引入的正则表达式功能是颗耀眼明珠。

90年代,随着Perl语言的发展,它的正则表达式功能越来越强悍。为了把Perl语言中正则的功能移植到其他语言中,PCRE(Perl Compatible Regular Expressions)派系的正则表达式也诞生了。现代编程语言如Python ,Ruby ,PHP ,C / C++ ,Java 等正则表达式,大部分都属于PCRE派系。

总的来说,经历20世纪80至90年代洗礼,正则表达式形成了两大派系:POSIX 与 PCRE。

正则表达式 - POSIX & PCRE


二、POSIX与PCRE

POSIX派系与PCRE派系具体有什么不一样?我们应该何时选择哪个派系?

POSIX派系

POSIX派系是遵循POSIX规则的正则表达式
其中代表软件有:grep ,sed和awk等

BRE和ERE标准

POSIX派系分为两种标准:
  1. BRE标准(Basic Regular Expression基本正则表达式)
  2. ERE标准(Extended Regular Expression扩展正则表达式)
在GNU版本下,两者具体差别如下:

正则表达式 - POSIX & PCRE

是不是很难找到两者的差别点呢?仔细留意一下,第 3,4,5,7 行的内容,我们能发现,如果使用BRE标准,需要对[],(),|符号进行转义。作者看来ERE实际上是BRE的一个扩展标准,开发者使用ERE能书写更简单的正则表达式,不需要对某些字符进行特殊转义。

POSIX字符组

POSIX派系有自己的字符组,叫POSIX字符组,具体解释如下所示:

正则表达式 - POSIX & PCRE

篇幅原因,仅提供部分需要关注的对比,具体看【附录-POSIX字符组详细内容】

PCRE派系

现代编程语言大部分都属于PCRE派系,如Python,PHP和Java 等。

PCRE与Perl

  • Perl1提供了正则表达式操作符——是通用脚本语言的首创

  • Perl2补充/i量词,能够进行不区分大小写匹配等

  • Perl3支持/e量词,能够增强替换运算符的能力;{min,max}区间量词等

  • Perl5 添加 非捕获的括号,忽略优先的量词,顺序环视功能等

随着Perl每次迭代,新增的特性使正则表达式本身逐渐成为一门强大的编程语言,并为其提供了进一步发展空间。也因为派系的整合,PCRE库横空出世,它是一套兼容Perl正则表达式库,全面仿制 Perl的正则表达式的语法和语义。其他开发人员可以把PCRE库整合到自己的工具和语言中,为使用者提供丰富的正则功能。

特性

  1. 更易用
    相对于POSIX派系的BRE标准,不需要使用进行转义

    例如:在多选分支结构直接使用|即可(1|2表达1或者2)

  2. 更简洁
    在兼容POSIX字符组的基础上还支持更简洁的写法:

    例如:w等价于[[:word:]],d等价于[[:digit:]]

  3. 更多功能

    例如:Look-around(环顾断言),Non-capturing Group(非捕获组),non-greedy(非贪婪)等。

总结

正因为PCRE与POSIX相比,PCRE使用起来更加易用简洁(不需要转义,有更简洁字符组),功能更加丰富(非捕获组,环顾断言,非贪婪)。
如果没有特殊原因,应尽可能使用PCRE派系,让正则匹配的结果更符合我们预期。

正则表达式 - POSIX & PCRE

篇幅原因,仅提供部分需要关注的对比,具体看【附录-PCRE、GNU BRE、GNU ERE对比】,如果读者对贪婪和非贪婪模式感兴趣,可以了解一下正则表达式的执行引擎,或许会让你对正则表达式产生新的看法。


三、实战

了解完PCRE派系和POSIX派系后,我们来做个简单的测试,文本内容如下,我们目标是需要匹配其中的数字:
12345
abcde
实验环境为Linux与macOS下的grep,分别使用:
  • 不带参数,为POSIX BRE模式

  • 带参数-E,为POSIX ERE模式,

  • 带参数-P,为PCRE模式(macOS不支持)

实验结果如下图:

正则表达式 - POSIX & PCRE

实验结论

在Linux环境下

通过man grep ,可以了解到Linux下的grep默认是POSIX BRE模式

正则表达式 - POSIX & PCRE

加上-E则是POSIX ERE模式

正则表达式 - POSIX & PCRE

加上-P则是PCRE模式

正则表达式 - POSIX & PCRE

在macOS环境下

从实验结果来看,grep ‘d’ demo.txt’ 命令在Linux与macOS输出是不一样的,这是因为 macOS自带的grep是BSD版本,而Linux下的grep则是GNU版本。macOS基于BSD,预置BSD工具链,众多命令行工具与Linux下GNU工具的行为不一致,例如常见的gzip ,find和sed ,以及本文重点提及的grep。
读者如果希望自己的macOS电脑能完美运行GNU/Linux上的Shell脚本,可以使用 homebrew来逐一替换,例如本文提及的grep可以通过brew install grep。


总结

正则表达式以及相关生态在发展了数十年的情况下,应用场景已经非常广泛。者在使用软件工具的时候,应需要了解该工具支持正则表达式何种派系,避免执行脚本迁移不同环境后运行结果不符合预期。
例如:
  1. 确认版本类型(GNU ,BSD)。建议统一使用GNU中grep程序,避免在不同环境下运行结果不符合预期的现状。
  2. 确认每个模式下的选项(BRE,ERE,PCRE)。尽可能选择PCRE模式,因为PCRE 模式更符合我们的使用习惯。
此外,除了关心正则表达式的标准之外,强烈推荐读者细读正则表达式的执行引擎,或许能帮助你写出更性能更好的正则表达式,避免因为正则表达式的地狱回溯导致的应用程序的OOM。


附录

POSIX字符组详细内容

正则表达式 - POSIX & PCRE

PCRE、GNU BRE、GNU ERE 对比

正则表达式 - POSIX & PCRE

正则表达式 - POSIX & PCRE

GNU

正则表达式 - POSIX & PCRE

BSD

BSD是加州大学伯克利分校对Unix系统进行的扩展与重新发行。目前的BSD生态系统围绕三大主要操作系统:
  1. FreeBSD、OpenBSD、NetBSD

  2. DragonFly BSD

  3. 其他发行版

参考资料

  • 《精通正则表达式》第3版

  • 07 | 正则有哪些常见的流派及其特性?

  • 正则表达式“派别”简述 – Keep Coding

  • 正则表达式的历史与几大流派 – 小蒋不素小蒋 – 博客园

  • Regex cheatsheet

  • GNU是什么,和Linux是什么关系?- 知乎

  • Difference Between Linux And BSD | Open Source Operating Systems

  • Unix,BSD,GNU 和Linux之间是什么关系?- 掘金

  • PCRE、GNU BRE、GNU ERE对比


招人正则匹配中,欢迎扫码命中
正则表达式 - POSIX & PCRE




正则表达式 - POSIX & PCRE

快乐工作,快乐生活

Happy work , Happy life


本篇文章来源于微信公众号: 腾讯CDC体验设计

UI/UX

如何打造下沉空间快闪店?

2021-11-8 16:30:00

UI/UX

数字化转型时代下的设计:数字孪生X智慧城市

2021-11-8 20:00:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索