正则表达式快速入门

正则表达式
正则表达式实质就是一串用来匹配相关文本的表达式


正则表达式的四种功能
为什么使用正则表达式?我们知道,在程序处理中,经常涉及文本处理,在这样一个恶劣的生存领域,除了正则表达式和更高级的parser技术外,可以说别无利器。有了正则表达式,就意味着你有了四大基本功能:
1. 检验相关文本段是否存在 
2.从资源中 提取相关文本段
3.从资源中 分割相关文本段
4. 替换资源中的相关文本段
可以看出,功能2和功能3是有点重复的,事实上,这几个功能都重复。。因为正则表达式核心功能就是" 文本匹配",对于文本的其他操作都可以基于匹配实现。要掌握这把利器,需要循序渐进地练习,但更多情况下,吓吓坏人,懂得"挥两下"就好了,


快速建立学习的框架

正则表达式处理的文本是由一个个字符构成的,最基本的操作当然也是针对单个字符的,这是框架的第一条主线。对多个字符同时进行操作,涉及到分组的概念,这是框架的第二条主线。

第一条主线:

元字符与普通字符 --> 字符组 --> 排除型字符组 --> 量词 --> 贪婪与懒惰

第二条主线:

分组 --> 多选结构 --> 引用分组 --> 命名分组

小分支:

锚点

以上是我归纳的有关正则表达式的学习路线,属于一次性可接纳吸收的知识,若只是需要“挥两下”正则表达式,这就足够了。接下来开始正文!



1.1元字符与普通字符
正则表达式是由元字符和普通字符构成的。元字符用来实现一些特殊的功能,普通字符则用来匹配文本字符。关于正则表达式有什么元字符,你可以在 《正则表达式元字符及说明》找到答案,这里就不再啰嗦了。
如果你想匹配某个字符,就在正则表达式中敲上那个字符,但如果你想匹配的字符,恰好是个元字符,那就需要转义。

转义只有一种方法,外加一种特殊情况(可以忽略)。这种方法就是使用转义符"\",将元字符转成普通字符。这里列举了几种常见情况。


与元字符相关的转义
元字符相关的文本转义方法
-\-
*\*
+\+
?\?
*?\*\?
+?\+\?
{n}\{n}
{m,n}\{m,n}
{m,}\{m,}
{,n}\{,n}
.\.
[mn]\[mn]



1.2字符组
字符组名字虽然带有“组”字,但实质还是单个字符。它的表达方式为[],中间放东西,比如[0123456789]只匹配一个数字,代表0至9这十个数字都可以被匹配,也可以写出[783461250],还可以用范围表示法表示,如[0-9]。此外字母也可以,如[a-z],因为其本质都是ASCII码。若还想简化,可以使用字符组简记法\d替代[0-9],各简记法如下表所示:
字符组简记法等价记法
\d[0-9]
\w

[0-9a-zA-Z]

\s[ \t\r\n\v\f]
\D除\d之外的所有字符
\W除\w之外的所有字符
\S

除\s之外的所有字符

因而由上表可以得出另外一个结论,<<[\s\S]>>可以匹配任意一个字符,同理<<[\w\W]>>和<<[\d\D]>>也是

这里还有一点需要注意,<<.>>点号其实不能匹配任意字符,因为\n换行符是个例外,真正能匹配任意字符的,只有以上说的这种形式

1.3排除型字符组

关于排除型字符组,你只需要知道三个点:
1.排除型字符组是字符组的一种,用来排除一个不想匹配的字符。
2.写法为[^reg],reg是你不想匹配的字符。
3.[^reg]是必须匹配一个字符的,只是不匹配你排除的字符而已。


1.4量词:

若想匹配多个相同的字符,如555555,当然可以继续用555555这个正则表达式来匹配,但更简单地是使用量词,如:5{6}可以替代555555。量词可以认为只有两种,一种是{}这样的,如下表所示:

量词说明
{n}之前的元素必须出现n次
{n,m}之前的元素最少出现n次,
最多出现m次
{m,}之前的元素最少出现m次
出现次数无上限
{0,n}之前的元素可以不出现
但最多出现n次

另外一种叫量词简记法,如下表所示:
量词简记法{m,n}等价形式说明
*{0,}可能出现,也可能不出现,出现次数无上限
+{1,}至少出现1次,出现次数没有上限
{0,1}至多出现1次,也可能不出现


1.5贪婪及懒惰:
正则表达式一般是贪婪的,什么意思?贪婪指的是,它会尽可能使匹配的量词最大化,但也可以让它变得懒惰,即只要匹配到符合要求的了,就停止匹配,如:
贪婪:<<[/s/S]*ivan>> 去匹配字符串“My name is ivan, not that ivan”,它会匹配整个字符串"My name is ivan, not that ivan"
懒惰:<<[/s/S]*?ivan>> 去匹配字符串“My name is ivan, not that ivan”,则匹配"My name is ivan"
懒惰模式与贪婪模式的写法如下:
贪婪懒惰
**?
++?
???
{m,n}{m,n}?
{m,}{m,}?
{,n}{,n}?
由上表可以看出,写法只是在量词后面加?,但有一点需要强调,贪婪与懒惰并不会改变原来量词的限定次数,如+或+?,均代表前面的元素至少出现一次,且出现次数无上限。


------------------------------------------------------------------------------------累死我了,下面的星期天旅游回来再写------------------------------------------------------------------
2.1分组:

刚才讨论的都是针对单个字符的操作,若想扩展到多个字符的情况,那就需要用到分组的功能。分组很简单就是用()将想要一起操作的多个字符括起来。若想对分组作量词操作,可以在分组后面紧跟量词,如(ab2){3},可以匹配ab2ab2ab2。当然除了量词操作外,还有几种针对分组的功能,常用的有:多选结构,引用分组,命名分组。


2.2多选结构:

表示方法就是(|),括号内|左右可分别填入字符,如(reg1|reg2)。多选结构其实就是或的意思。需要注意的是,若文本里,reg1和reg2都能匹配,正则表达式会按照顺序从左到右匹配,因而这里将匹配到reg1,而不是reg2。如在文章里,用多选结构(河南|河南省)匹配相应的文本,则匹配出来的都将是“河南”,包括原本文章中“河南省”中的“河南”。


2.3引用分组:
正则表达式中一般会有多个分组,每个分组匹配完成后,正则表达式都会记录下这个分组匹配到的文本,这意味着,可以调用各个分组匹配到的文本。
引用分组的表达方法
表达形式就是\接数字,比如\3,即表示第3个文本匹配到的文本。一个正则表达式一般会有多个分组,有可能是嵌套分组,分组的编号,按照左括号,从左到右依次增加,如:

(((\d{3})-(\d{2}))-(\d{2}))

 0   |   |          |     |          |   |      |          |   |

 1   |   |          |     |          |   |      |          |   |

     2   |          |     |          |   |      |          |    

          3         |     |          |          |          |    

                           4         |         |          |    

                                                 5         |    


2.4命名分组:

除了按照编号引用分组外,你还可以命名分组,其结构如下图所述:

字符串:        2013           -           05                 -         27

表达式:(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})

分组名:         year                      month                      day

命名分组的表达式有很多,上面是Python的记法,用(?P<name>...)来分组。

根据编号或命名引用分组有什么作用呢?这里分别以匹配,替换及提取为例,说明如下:


操作匹配字符串正则表达式结果说明
匹配shoot([a-z])\1oo

用于查找连续重叠字母。括号内[a-z]匹配第一个字母,

\1用于反向引用,实现查找连续字母的功能

替换2013-05-27re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\2/\3/\1", "2013-05-27")05/27/2013

re.sub()是Python与正则表达式相关的函数,

它的第一个参数使用正则表达式匹配字符串,

第二个参数使用引用分组进行替换操作,

第三个参数是源字符串

提取2012-03-14re.search(r"(\d{4})-(\d{2})-(\d{2})", "2012-03-14").group(3)14

re.search()同样是Python与正则表达式相关的函数,

它的第一个参数使用正则表达式匹配字符串,

第二个参数是源字符串,group(3),代表提取的编码

为3的分组,即/3


针对引用分组,需要特殊说明的是,当分组匹配成功后,引用分组也被固化为匹配到的文本了。


3.1锚点:

锚点和一般的正则表达式符号不同,它不匹配任何字符。相反,他们匹配的是字符之前或之后的位置。

“^”匹配一行字符串第一个字符前的位置。<<^a>>将会匹配字符串“abc”中的a。<<^b>>将不会匹配“abc”中的任何字符。

类似的,$匹配字符串中最后一个字符的后面的位置。所以<<c$>>匹配“abc”中的c。

这里介绍三个常用的锚点:

锚点说明
^行首
$行尾
\b单词的开始或结束
(单词边界)

--------------------------------------------------------------正文部分至此结束---------------------------------------------------------------------

以上部分属于我一次性能记下的有关正则表达式的基础内容。学的时间很短,但是写这文章花费的时间却很长,主要难点在于整理出一个知识的框架,这样即便过了很久,也不会忘记相关的内容。实质上有关正则表达式的基础内容还有几方面没有涵盖到:

1.分组的非捕获分组

2.分组的断言,环视

3.匹配模式

这三部分内容其实也比较简单,可以参考相关的博文,过一遍基本就会用了。


最后附上本文的参考资料:

1.《正则指引》

2.http://dragon.cnblogs.com/archive/2006/05/08/394078.html

3.http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html

都是中文的,推荐大家看看,另外还有一个专门介绍正则表达式的博客

http://iregex.org/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值