python之正则表达式教程(初级)

来源:互联网 发布:台风莫兰蒂数据 编辑:程序博客网 时间:2024/05/01 05:35

本文对我们常用的正则表达式语法进行总结,并根据实例来讲解,希望大家能够有所收获。

一、纯字符串匹配

这一类是最简单的,也是字符串操作可以代替的,但是我们还是以这种匹配开始我们的教程,介绍正则的基本思想。

import restr = "hello,everyone,I am HelloHaibo,thank u for watching my blog"pattern = re.compile(r'Haibo')content = re.findall(pattern,str)print content

输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['Haibo']

说明在str中找到了我们需要的纯字符串,如果我把pattern = re.compile(r'Haibo')换成pattern = re.compile(r'haibo'),则会提示没有找到元素,说明匹配的内容与你事先定义的是要完全匹配的,区分大小写。

其实上述做法并没有太大意义(对于纯字符串正则匹配来说),普通的字符串操作即可满足要求,并且可能更有效的解决问题。但是正则表达式的灵活性却是字符串操作不可比拟的,下面的几种匹配是我们常用的。

二、单字符匹配

其实我们大多数时候并不知道我们匹配的字符具体是什么,我们只知道他们是属于那一类,像它属于数字啊,小写字母啊,特殊字符啊这样的,这样就需要我们正则表达式出马。我们来先看看单字符匹配

第一种 : . 单一个点,匹配任何一个字符,但是除了\n(换行符)

import restr = "hello,everyone,I am HelloHaibo,thank u for watching my blog"pattern = re.compile(r'.ello')content = re.findall(pattern,str)print content

输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['hello', 'Hello']
说明.把H和h都匹配到了,其实就算再字符串里存在这样的,fello、dello、8ello这样字符串,他也是能查找到的。但是一个.只匹配一个任意字符,想匹配多个任意字符就要写多个.

第二种:\d \D,其中\d匹配单一个纯数字,\D匹配一个除了数字之外的字符,两个集合刚好互为补集。

import restr2 = "1 + 2 = 3,yeah"pattern = re.compile(r'\d')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['1', '2', '3']
可见\d把数字都匹配出来了,让我们再用\D匹配一下:

import restr2 = "1 + 2 = 3,yeah"pattern = re.compile(r'\D')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py[' ', '+', ' ', ' ', '=', ' ', ',', 'y', 'e', 'a', 'h']
可见,\D把除了数字以外的全部都匹配了。

第三种: \w \W,其中\w匹配英文单词字符a-z A-Z 0-9,\W反之.

import restr2 = "1 + 2 = 3,Yeah"pattern = re.compile(r'\w')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['1', '2', '3', 'Y', 'e', 'a', 'h']
\w把字符串里的数字,小写字母,大写字母都匹配出来了
import restr2 = "1 + 2 = 3,yeah"pattern = re.compile(r'\W')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py[' ', '+', ' ', ' ', '=', ' ', ',']
\W把除了数字,小写字母,大写字母以外的都匹配出来了。


三、字符集合匹配

第一种: []方括号,代表字符集合

第二种: -连字符,标识一个范围(对应ASCII表)0-4,表示匹配,0 1 2 3 4,它需要跟[ ]配套使用.

import restr2 = "1 + 2 = 3,yeah"pattern = re.compile(r'[0-4]')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['1', '2', '3']

import restr2 = "1 + 2 = 3,yeah"pattern = re.compile(r'[a-z]')content = re.findall(pattern,str2)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['y', 'e', 'a', 'h']
现象大家可以自行观察

第三种: * ? +这三个字符用的几率非常大,首先说一下

* 匹配前一个字符零次或者无限次

import restr1 = "http https httpes httpsss"pattern = re.compile(r'https*')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['http', 'https', 'http', 'httpsss']
可以看出,http后面跟零个或者更多个s的都被匹配出来了


+ 表示匹配前面的字符一次或者无限次

下面将*换成+,大家看看会匹配到什么

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['https', 'httpsss']
可以看出http没有被匹配上,因为s至少要匹配一次


? 表示匹配前一个字符零次或者一次

import restr1 = "http https httpsss"#str2 = "1 + 2 = 3,yeah"pattern = re.compile(r'https?')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['http', 'https', 'https']
可见,httpsss中的https也被匹配到了,这是我们不想遇到的,所以我们有时候需要规定匹配的次数,而并不是让算法自己无休止的匹配下去

第四种: {m,n}匹配前一个字符m-n次,即m-n中的任意次数都行,包括m和n,将上述代码稍加修改:

import restr1 = "http https httpsss"#str2 = "1 + 2 = 3,yeah"pattern = re.compile(r'https{0,1}')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['http', 'https']
这样匹配的就是https或者http啦,当然{}里面也可以只有一个数字,那表示匹配前一个字符固定次数。


第五种:以上各种规则可以自由组合,形成功能强大的正则表达式

实例1:

import restr1 = "hello,everyone,I am HelloHaibo,thank u for watching my blog"pattern = re.compile(r'[Hh]ello')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['hello', 'Hello']
这个规则只匹配Hello或者hello,[ ] 虽然表示一个集合,但是也是匹配单个字符的。

实例2:找出标签中的网址

import restr1 = "<h1>www.baidu.com</h1><h2>www.imooc.com</h2><span>tttt</span>"pattern = re.compile(r'<h[\d]>www\.[a-zA-Z]+\.com</h[\d]>')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['<h1>www.baidu.com</h1>', '<h2>www.imooc.com</h2>']
我们来分析一下:外围的<h[\d]>和</h[\d]>表示匹配<h1></h1>或者h2、h3、h4这样的标签;www\.表示匹配www.那为什么要加一个\呢,因为.在正则表达式中已经有特殊意义了,如果你直接写www.他会匹配www后面跟一个任意字符,所以我们需要一个转义符号,来说明我们就想匹配.本身;[a-zA-Z]+要匹配a-zA-Z这些字符一次或者任意次;\.com表示匹配.com这个字符串,当然实际中要考虑网址的多样性,后缀的多样性等等

四、断言匹配

准确说这个里面的核心思想是判断

(?<=...)和(?=...)两个分别称为后向匹配和前向匹配,它们判断是否成立,但是不参与匹配输出,我们可以把上述实例2修改:

import restr1 = "<h1>www.baidu.com</h1><h2>www.imooc.com</h2><span>tttt</span>"pattern = re.compile(r'(?<=<h[\d]>)www\.[\w]+\.com(?=</h[\d]>)')content = re.findall(pattern,str1)print content
输出:

C:\Python27\python.exe E:/Projects/pytext/博客临时测试/test.py['www.baidu.com', 'www.imooc.com']
可以看到我把实例2中的<h[\d]>和</h[\d]>修改为(?<=<h[\d]>)和(?=</h[\d]>),说明我要判断我要匹配的字符串开头是不是以<h1>、<h2>、<h3>....这样的标签开头,以</h1>、</h2>、</h3>...这样的标签结束,但是输出结果可以看出,并没有标签本身,只是把标签中间的内容输出,这在我们分析网页内容时候至关重要。

最后在啰嗦一下,我们的日常使用基本就是上述规则的组合,同一种匹配结果可以有很多种方法,很难说谁的匹配时对的,谁的是错的,只能说效率高低,或者构造的pattern的简洁度的高低。另外推荐一本书《正则表达式必知必会(修正版)》写的很不错CSDN资源可以搜索到,内容也不多,一天就可以读完,建议想全面了解正则表达式的同学可以看一看。

OK,上述内容基本可以满足你的日常使用,当然正则表达式还是有一些高级的语法,但是都不常用,可以在需要的时候去查阅,希望大家读完这篇文章可以有多收获,谢谢大家。