关于正则的迷思

简介:

正则是我们日常编程中一定会使用到的,不管是各种语言中的正则匹配,还是linux/unix系统上的grep/egrep命令,都是在使用正则来匹配字符串。随着用的深入,可能会感到越来越迷惑:

为什么有的语言要提供多种正则匹配的函数集?

-- 比如php的preg系列和ereg系列

为什么有的正则语句在不同的语言上匹配出来的东西是不一样的?

-- 比如unix的grep命令和perl语言的grep

故事从头开始讲
正则表达式(Regular Expression)从1956年就开始出现这个概念,后来Unix之父Ken Tompson将这个概念引入Unix,出现了grep工具。但是随着Unix的版本不断演化,Unix的差异也越来越大,一统江湖的POSIX标准就此出现。POSIX(Portable Operating System Interface for uniX)提供的是统一的Unix接口,当然也把正则这块统一了。于是出现了Posix的两种标准:POSIX Basic Regular Expressions (BRE)和POSIX Extended Regular Expressions(ERE)。

BRE就是现在unix系统使用的grep命令,ERE就是现在unix系统使用的egrep命令。ERE就是BRE的扩展包的意思,基本语法都是一样的,但是两者还是有一些区别,比如对于一些特殊符号,“{ }”是否需要使用反斜杆:

要匹配“tt”,在BRE中使用“t{1,2}”,在ERE中则是使用“t{1,2}”

Image

BRE和ERE还有的区别就是ERE多了+,?。具体可以看这篇文章:http://www.regular-expressions.info/posix.html

PS:现在网络上说的正则,如果没有特殊说明,应该都是指的是ERE。它也是现在使用最广的正则了。

PS2:grep -e就和egrep是一样的。

故事继续
如果世界上的正则只有一种标准,那一切看起来都这么完美,但是在计算机世界总是有各种各样的历史问题。

有很多种语言也自己定义了一套正则标准,虽然大体上和POSIX的这套很像,但总还是有一些不同的细节的。比如Perl,python,Tcl(Tool Command Language)。都有自己定义的一套正则标准。其中Perl的正则到现在演化成为PCRE(Perl Compatible Regular Expressions)。这个正则语法也是被php所采用的。

GNU grep,linux机器上使用最广泛的正则语法,几乎所有的linux机器上的grep命令都是GNU grep。它和POSIX是一致的,有GNU Basic Regular Expressions 和GNU Extends Regular Expressions。

关于各种版本的正则的不同可以查看这篇http://www.greenend.org.uk/rjk/tech/regexp.html

PHP中的正则
PHP中有两套正则函数集:preg和ereg (如果你算上mb_ereg那就有三套)

preg和ereg分别代表的是PCRE regular Expression和Posix extension regular Expression。preg和ereg有一些不同,最大的不同就是preg有“分隔符”(一般是或者|)来将正则表达式划出来。还有就是preg是没有大小写不同的函数的,它使用“模式修饰符”来对大小写进行匹配。下面是摘自php文档的函数对照表:

Image(1)

文档中提到的一个例子需要注意下的:

one(self)?(selfsufficient)? 匹配字符串“oneselfsufficient ” 在ereg是会匹配出oneselfsufficient的,但是在preg是匹配到oneself的。就是说posix会尽可能的匹配正则,而对于这种可“多种”匹配的正则,pcre的选择更为保守。

Go中的正则
go中的正则包是regexp,它使用的是叫做RE2(https://code.google.com/p/re2/wiki/Syntax)这个C++写的库,这个库支持了两种标准:Perl 和 POSIX

在函数中也有体现

MustCompile

MustCompilePOSIX

所以呢,下面这个代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
import(

"regexp"
"fmt"

)
func main() {

var origin1 = `tt`
var reg = `t\z`
matches1 := regexp.MustCompile(reg).FindString(origin1)
fmt.Println(matches1)

/*

matches2 := regexp.MustCompilePOSIX(reg).FindString(origin1)
fmt.Println(matches2)

*/
}
z是只在perl的正则语法存在,表示以t为结尾,在POSIX中没有,所以如果你把注释的部分放开,这个程序就会抛出panic

go的RE2支持哪些语法可以看https://code.google.com/p/re2/wiki/Syntax 这个页面说明

本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2013/04/15/3021518.html,如需转载请自行联系原作者

相关文章
|
7月前
|
算法 搜索推荐 程序员
第六十二练 字符串匹配 - 模糊匹配
第六十二练 字符串匹配 - 模糊匹配
65 1
|
4月前
|
Java
【正则秘籍】四大匹配模式:揭秘文本处理的终极武器!
【8月更文挑战第25天】本文以问答形式深入介绍了正则表达式中的四种关键匹配模式:贪婪匹配、非贪婪匹配、先行断言与后行断言。通过具体的Java示例代码,展示了每种模式的工作原理及应用场景。贪婪匹配适用于提取最长匹配串,而非贪婪匹配则用于获取最短匹配。先行断言确保匹配后的内容符合特定模式,而后行断言则检查匹配前的内容不符合指定模式。了解并熟练运用这些模式对于提高文本处理能力至关重要。
57 2
|
前端开发 JavaScript 数据安全/隐私保护
关于正则表达式,小黄人有话要说!!!
本文将带你逐步学习正则表达式的基础知识和高级技巧,从基本的元字符到实用的正则表达式示例,让你轻松掌握这一重要的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都能帮助你更好地理解和应用正则表达式。
122 0
关于正则表达式,小黄人有话要说!!!
|
运维 Linux 程序员
网友来稿:何为正则?一正则天下,一文带你看尽精华。
网友来稿:何为正则?一正则天下,一文带你看尽精华。
|
算法
火力全开—模式匹配KMP算法
火力全开—模式匹配KMP算法
168 0
火力全开—模式匹配KMP算法
|
自然语言处理 测试技术 程序员
秒懂正则匹配,领略正则魅力
秒懂正则匹配,领略正则魅力
204 0
秒懂正则匹配,领略正则魅力
|
数据可视化 计算机视觉
滚蛋吧,正则表达式!
滚蛋吧,正则表达式!
630 1
滚蛋吧,正则表达式!
|
存储 缓存 移动开发
|
数据采集 Python
正则表达式很难吗?其实也就那样!
正则表达式很难吗?其实也就那样!
283 0
正则表达式很难吗?其实也就那样!
|
算法 Java API
【算法攻坚】实现简易正则匹配
【算法攻坚】实现简易正则匹配
134 0