无处不在的正则表达式
来源:互联网 发布:js给div添加标签 编辑:程序博客网 时间:2024/05/21 11:28
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开发的,为很多现代工具所使用的库。
2。正则表达式语法
正则表达式有多种不同的风格。下表是在PCRE中元字符及其在正则表达式上下文中的行为的一个完整列表:
n
”匹配字符“n
”。“\n
”匹配一个换行符。串行“\\
”匹配“\
”而“\(
”则匹配“(
”。\n
”或“\r
”之后的位置。\n
”或“\r
”之前的位置。z
”以及“zoo
”。*等价于{0,}。zo+
”能匹配“zo
”以及“zoo
”,但不能匹配“z
”。+等价于{1,}。do(es)?
”可以匹配“does
”或“does
”中的“do
”。?等价于{0,1}。o{2}
”不能匹配“Bob
”中的“o
”,但是能匹配“food
”中的两个o。o{2,}
”不能匹配“Bob
”中的“o
”,但能匹配“foooood
”中的所有o。“o{1,}
”等价于“o+
”。“o{0,}
”则等价于“o*
”。o{1,3}
”将匹配“fooooood
”中的前三个o。“o{0,1}
”等价于“o?
”。请注意在逗号和两个数之间不能有空格。oooo
”,“o+?
”将匹配单个“o
”,而“o+
”将匹配所有“o
”。\
n
”之外的任何单个字符。要匹配包括“\
n
”在内的任何字符,请使用像“(.|\n)
”的模式。\(
”或“\)
”。(|)
”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)
”就是一个比“industry|industries
”更简略的表达式。Windows(?=95|98|NT|2000)
”能匹配“Windows2000
”中的“Windows
”,但不能匹配“Windows3.1
”中的“Windows
”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。Windows(?!95|98|NT|2000)
”能匹配“Windows3.1
”中的“Windows
”,但不能匹配“Windows2000
”中的“Windows
”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始(?<=95|98|NT|2000)Windows
”能匹配“2000Windows
”中的“Windows
”,但不能匹配“3.1Windows
”中的“Windows
”。(?<!95|98|NT|2000)Windows
”能匹配“3.1Windows
”中的“Windows
”,但不能匹配“2000Windows
”中的“Windows
”。z|food
”能匹配“z
”或“food
”。“(z|f)ood
”则匹配“zood
”或“food
”。[abc]
”可以匹配“plain
”中的“a
”。[^abc]
”可以匹配“plain
”中的“p
”。[a-z]
”可以匹配“a
”到“z
”范围内的任意小写字母字符。[^a-z]
”可以匹配任何不在“a
”到“z
”范围内的任意字符。er\b
”可以匹配“never
”中的“er
”,但不能匹配“verb
”中的“er
”。er\B
”能匹配“verb
”中的“er
”,但不能匹配“never
”中的“er
”。c
”字符。[A-Za-z0-9_]
”。[^A-Za-z0-9_]
”。\x41
”匹配“A
”。“\x041
”则等价于“\x04&1
”。正则表达式中可以使用ASCII编码。.(.)\1
”匹配两个连续的相同字符。3。正则表达式引擎
正则引擎主要可以分为两大类:一种是DFA,一种是NFA。这两种引擎都有了很久的历史,当中也由这两种引擎产生了很多变体!于是 POSIX的出台产生规范了不必要变体的继续产生。这样一来,目前的主流正则引擎又分为3类:一、DFA,二、传统型NFA,三、POSIX NFA。
DFA 引擎在线性时状态下执行,因为它们不要求回溯(并因此它们永远不测试相同的字符两次)。DFA 引擎还可以确保匹配最长的可能的字符串。但是,因为 DFA 引擎只包含有限的状态,所以它不能匹配具有反向引用的模式;并且因为它不构造显示扩展,所以它不可以捕获子表达式。
传统的 NFA 引擎运行所谓的“贪婪的”匹配回溯算法,以指定顺序测试正则表达式的所有可能的扩展并接受第一个匹配项。因为传统的 NFA 构造正则表达式的特定扩展以获得成功的匹配,所以它可以捕获子表达式匹配和匹配的反向引用。但是,因为传统的 NFA 回溯,所以它可以访问完全相同的状态多次(如果通过不同的路径到达该状态)。因此,在最坏情况下,它的执行速度可能非常慢。因为传统的 NFA 接受它找到的第一个匹配,所以它还可能会导致其他(可能更长)匹配未被发现。
POSIX NFA 引擎与传统的 NFA 引擎类似,不同的一点在于:在它们可以确保已找到了可能的最长的匹配之前,它们将继续回溯。因此,POSIX NFA 引擎的速度慢于传统的 NFA 引擎;并且在使用 POSIX NFA 时,您恐怕不会愿意在更改回溯搜索的顺序的情况下来支持较短的匹配搜索,而非较长的匹配搜索。
目前使用DFA引擎的程序主要有:awk,egrep,flex,lex,MySQL等;
使用传统型NFA引擎的程序主要有:GNU Emacs,Java,egrep,less,more,.NET,PCRE library,Perl,PHP,Python,Ruby,sed,vi;
使用POSIX NFA引擎的程序主要有:mawk,GNU Emacs(使用时可以明确指定);
也有使用DFA/NFA混合的引擎:GNU awk,GNU grep/egrep,Tcl。
那么如何测试正则引擎的类型呢?可以分成两步来测试:
1)判断是否是传统型NFA, 首先看看忽略优先量词*?,+?,??,{n,m}?是否得到支持?若是,基本就能确定是传统的NFA,
2)接下来区分DFA与POSIX NFA, 只需判断是否支持捕获型括号和回溯,若不支持则为DFA。也可能存在同时使用两种引擎的混合系统,在这种系统中,如果没有使用捕获型括号,就会使用DFA。
4。正则表达式应用场景
1)linux帮助信息
我们经常性在linux的帮助信息里能看正则表达式的应用,如下查询chmod命令的帮助信息时就会提示“Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.”
billfeller@billfeller:~/Desktop$ chmod --help
Usage: chmod [OPTION]... MODE[,MODE]... FILE...
or: chmod [OPTION]... OCTAL-MODE FILE...
or: chmod [OPTION]... --reference=RFILE FILE...
Change the mode of each FILE to MODE.
-c, --changes like verbose but report only when a change is made
--no-preserve-root do not treat `/' specially (the default)
--preserve-root fail to operate recursively on `/'
-f, --silent, --quiet suppress most error messages
-v, --verbose output a diagnostic for every file processed
--reference=RFILE use RFILE's mode instead of MODE values
-R, --recursive change files and directories recursively
--help display this help and exit
--version output version information and exit
Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.
Report chmod bugs to bug-coreutils@gnu.org
2)shell
grep awk 给出实例截图 接口日志分析与天气日志分析
3)vim
1。你有如下样式的一个名字列表:
Doe, John
Smith, Peter
你想把它改成:
John Doe
Peter Smith
这可以用一个命令完成:
:%s/\([^,]*\), \(.*\)/\2 \1/
2。在vim中删除所有行尾的多余的tab键和空格: %s/\s*$//g
3.在vim中所有行首或行尾添加一些字符串
:3, %s/^/some string/g 从第3行至文件末尾的每一行行首添加some string
:%s/$/some string/g 在全文行尾添加some string
:%s/string1/string2/g 替换全文中的string1为string2
:3, 7s/string1/string2/g 用string2替换3-7行的string1
:%s/\n//g 删除所有行尾的换行符
其中,s表示substitude,g表示global,%表示所有行
4)php
PHP提供了三套独立的,不相关的正则引擎,分别是preg, ereg, mb_ereg。其中最常用的preg使用的是NFA引擎,通常情况下preg 在速度和功能方面都要强于其余两者。
Preg函数列表
preg_filter —执行一个正则表达式搜索和替换
preg_grep —返回匹配模式的数组条目
preg_last_error —返回最后一个PCRE正则执行产生的错误代码
preg_match_all —执行一个全局正则表达式匹配
preg_match —执行一个正则表达式匹配
preg_quote —转义正则表达式字符
preg_replace_callback —执行一个正则表达式搜索并且使用一个回调进行替换
preg_replace —执行一个正则表达式的搜索和替换
preg_split —通过一个正则表达式分隔字符串
参与阅读:《精通正则表达式》 Jeffrey E.F.Friedl著
Vim学习总结
正则表达式 维基百科,自由的百科全书
http://www.360doc.com/content/08/1008/14/19694_1729202.shtml
Regexp Syntax Summary
- 无处不在的正则表达式
- 【无处不在的正则表达式】正则表达式在Vim中的应用
- 无处不在的字符集
- 无处不在的"SQL注入"
- 人生的变化无处不在!
- 无处不在的Party
- 无处不在的白板
- 无处不在的垃圾收集
- 无处不在的云
- 无处不在的Bug
- 无处不在的分析能力
- 无处不在的Framework
- 无处不在的二分搜索
- 无处不在的二分查找
- 无处不在的线性分解
- 无处不在的家
- 无处不在的百度招聘
- 无处不在的日期类
- 跟我一起写 Makefile(八)
- Everything使用技巧
- 人工智能的历史
- 查看、设置与修改MySQL字符集
- 链式队列的实现
- 无处不在的正则表达式
- 我的学习环境!
- Unix & Windows 创建 Oracle数据库实例 (Oracle 10g为例)
- MFC中的ComboBox的使用
- 目前是创业者进入医疗IT领域的大好时机
- flash中注册时间的第四个参数useWeakReferences
- QT学习小技巧
- 查询mysql数据库(某个数据库)某张表的所有列名;查询某个数据库所有表名
- 值类型介绍——float类型