正则表达式

来源:互联网 发布:vmware player mac 编辑:程序博客网 时间:2024/05/15 04:42

概述

正则表达式本身是一种工具,但需要依赖具体的编程语言实现.对于文本型数据,搜索,匹配,替换等常用操作,正则表达式就是一个神器.

正则表达式最出名的书籍莫过于精通正则表达式,但是确实有些厚.现在很难有时间深入学习正则表达式.先学习一些基础东西.学习正则表达式这本书,这两年刚出来的,确实还不错,讲的比较简单,适合入门.正则表达式更多的需要实践.

整理下这两天的笔记.


笔记

在使用时有的工具(例如grep使用基本正则表达式时)需要字符前增加转义字符,例如( ) | { },grep -E模式(扩展的正则表达式)的话就不需要转义字符.

[ ] 元字符
[1-9]字符组字符集
\d=[0-9]匹配数字
. 匹配任意字符
{3} 包含数字的花括号是一种量词 (*)零个或多个 (+)一个或多个
? 量词0个或1个.
^ 脱字符,一行起始位置
| 表示选择,从多个可选项(不是单个字符)中选择一个  // .|-与 [.-]区别??? |选项可以是格式,而[]里面只能是字符.
$ 匹配行结束位置.
\D 匹配非数字字符[^0-9],[^\d]
\w 匹配所有单词字符,字母数字下划线.[_a-zA-Z0-9]
\W匹配非单词字符,空格标点其他非字母,非数字字符[^_a-zA-Z0-9]
[\b] 退格字符
\0 空字符
\s 匹配空白符[ \t\n\r]匹配空格制表符,换行符,回车符
\S 匹配非空白字符
\b 匹配单词边界,不消耗任何字符.

断言:零宽度断言,不匹配字符,而是匹配字符串中的位置
行或字符串的起始与结束位置^ $
单词边界\b 
主题词的起始与结束位置
引用字符串字面值的边界.

\B 来匹配非单词边界.这个实质就是匹配不在开始或结束位置的字符.一边或两边是否非单词边界.
指定单词边界的另一种方法是\<  \>

\A主题词匹配.(貌似在grep中不管用)
元字符串字面值\Q\E之间的字符

(?i)不区分大小写.[grep中无效,grep中使用 -i选项]

子模式,分组中的一个或多个分组,子模式就是模式中的模式.括号对于子模式不是必须的
(the|The|THE) 算是一种子模式,之间没有相互依赖关系.
(t|T)h(e|eir)子模式依赖前面的模式.

(\d)捕获分组,使用括号捕获分组,使用 \1对捕获的数字进行反向引用
当一个模式的全部或部分内容由一堆括号分组时,对内容进行捕获并临时存储在内存中,可以通过后向引用重用捕获的内容,形式为\1或$1.sed只接受\1,而perl两种都接受.

perl
\l 不匹配任何字符,将紧接其后的字母变为小写
\u 将紧接其后的字母变大写
\U 将其后的文本字符串全部变为大写.这里有个问题,怎么结束变为大写.??
\L 将其后的文本字符串全部变为大写.

命名分组:有名字的分组,通过名字而不是数字引用分组.
(?<one>xxxx)同样适用()捕获分组.
$+{one}引用分组.





非捕获分组,不会将其内容存储在内存中,不想引用分组的时候可以使用它.由于不存储内容,非捕获分组带来更高的性能.个人理解就是捕获到的分组不需要再后面向后引用,只是使用这一次,这样减少存储在内存中的数据,加快速度.
(the|The|THE)不需要向后引用时,可以使用非捕获分组(?:the|The|THE)
如果需要将选项变为不区分大小写模式,推荐(?i:the) 选项i在问好和冒号之间.

原子分组:一种非捕获分组.使用正则表达式引擎进行回溯操作,这种分组可以将回溯操作关闭,但只针对原子分组内的部分,而不针对整个正则表达式.
???回溯操作是什么操作..

字符集并集与差集
字符集并集:[0-3[6-9]]
差集:[a-z&&[^m-r]]

POSIX字符组




匹配unicode字符
\u十六进制值




这个表里面应该是不同首字符后跟几个十六进制字符.


匹配unicode字符属性:某些实现中可以匹配unicode的字符属性,属性包括字符是否是字母,数字或标点符号.





匹配控制字符:上面一条可以匹配字符属性,可以匹配属性为控制的字符,但是不能单个准确匹配.
\cx x为匹配的控制字符


量词:量词自身是贪心的,贪心的量词会首先匹配整个字符串,尝试匹配时, 选定尽可能多的内容,也就是整个输入.量词首次尝试匹配整个字符串,如果失败则回退一个字符后再次尝试.这个过程叫做回溯.每次回退一个字符知道找到匹配的内容或者没有字符可尝试为止.记录所有的行为,相较另两种方式对资源消耗最大.
懒惰的量词:从目标起始位置尝试搜索匹配,每次检查字符串的一个字符,寻找匹配的内容,最后尝试匹配整个字符串.使一个亮丝成为懒惰的,必须在普通量词后添加一个?
占有量词会覆盖整个目标然后尝试寻找匹配的内容,只尝试一次,不会回溯.占有量词就是在铍铜量词之后添加一个+.
基本量词默认是贪心





匹配特定次数,花括号是最灵活和精确的量词.





懒惰量词基本的特性是匹配尽可能少的字符.
尽可能匹配最少符合条件的字符.





占有量词,很像贪心式匹配,会选定尽可能多的内容,但贪心是匹配不同的时不进行回溯.不放弃所找到的内容.优点是速度快,因为无需回溯,匹配失败的话也很快.占有式匹配有助于提高匹配的性能.
当知道文本内容时,知道哪里可以找到匹配,应该会使用占有量词.
这里不是很理解占有式匹配.主要在于自己测试grep的结果和书上不一样.
按照帖子上的解释还是能够理解.
如a*a
*是匹配优先的,也就是说先匹配,如果正则的后续部分不能再匹配,就回溯,在这个例子中,匹配字符串aaa的时候,首先a*匹配到最后一个,然后发现正则后面还有一个a没法匹配,就会将a*回溯到字符串的中间一个a,这时候正则中的最后一个a与字符串的最后一个a正好匹配,匹配结束

如果正则是a*+a
*+是占有优先,也就是说*+前面的字符会尽可能匹配,匹配了的就不会再回溯,不会让回去了,即所谓占有。如果字符串是aaa,那么这个例子中匹配过程就是a*+匹配了字符串的三个a,正则中的最后一个a不会再被匹配,因为a*+不会回溯
http://bbs.csdn.net/topics/390269371






环视:一种非捕获分组,根据某个模式之前和之后的内容匹配其他模式.成为零宽度断言.
环视包括:正前瞻,反前瞻,正后顾,反后顾.
正前瞻:紧随其后的符合某个格式.
pattern1(?=pattern2)
想过为什么要用前瞻,直接用格式匹配不可以么?这里在于前瞻模式只返回pattern1不返回pattern2.grep中前瞻反前瞻都不管用,可能是因为grep匹配结果输出是行,而不是匹配的字符.

反前瞻:匹配某个模式时,需要在它后面找不到含有给定前瞻模式的内容.
pattern1(?!pattern2)

正后顾:与正前瞻方向相反,查看左边的内容
(?<=pattern1)pattern2,返回pattern2

反后顾:与反前瞻方向相反,查看左边内容.含义与正后顾对应.
(?<!pattern1)pattern2,返回pattern2前面不符合pattern1的pattern2.

匹配邮箱的一个正则表达式
^([\w-.!#$%&'*+-/=?^_`{|}~]+)@((?:\w+\.)(?:[a-zA-z]{2,4})$


0 0