Python正则表达式

本文档原文来自:http://www.imooc.com/learn/550


正则表达式的概念

1. 使用单个字符串来描述匹配一系列符合某个语法规则的字符串;
2. 是对字符串操作的一种逻辑公式;
3. 应该场景:处理文本和数据;
4. 正则表达式的过程:依次拿出表达式和文本进行比较操作,如果每一个字符都匹配成功,则成功,否则匹配失败

python的第一个正则表达式

**import re**: Python正则表达式模块
re.compile(字符串模板)
pattern.match(被匹配的字符串)

字符串模板-->Pattern-->Match-->Result
    import re
    str = 'Hello python'
    pa_1 = re.compile(r'Hello')#前面的r表示匹配模板的字符串是元字符串,这样就生成了一个pattern的实例
    ma = pa_1.match(str)#ma是一个match对象
    print ma_1.group()#返回匹配到的字符串
    print ma_1.span()#返回被匹配字符串在原字符串的索引位置

    pa_2 = re.compile(r'hello', re.I)#表示忽略大小写
    ma = pa_2.match(str)#此时str字符串无论包含大写字符还是小写字符都会被匹配出来

注意点:
- 最好使用元字符串‘r’
- 最好生成一个pattern对象去match字符串

Python正则表达式的基本语法

  • . 匹配任意字符(除了\n)
  • […] 匹配字符集
>>> ma = re.match(r'[abc]', 'a')
>>> ma.group()
a
>>> ma = re.match(r'[abc]', 'd')
>>> ma
    #结果显示为空,说明ma没有匹配到正确的结果
>>> ma = re.match(r'[a-z]', 'd')
>>> ma.group()
d #[a-z]表示匹配a-z的任何字符
>>> ma = re.match(r'[a-zA-Z]', 'A')
>>> ma.group()
A
>>> ma = re.match(r'[a-zA-Z0-9]', '9')
>>> ma.group()
9
  • \d / \D 匹配数字/非数字
  • \s / \S 匹配空白/非空白字符
  • \w / \W 匹配单个字符[a-z A-Z 0-9] / 非单个字符
  • * 匹配前一个字符0次或者无限次
>>> ma = re.match(r'[A-Z][a-z]', 'Aa')
Aa
>>> ma = re.match(r'[A-Z][a-z]', 'A')
>>> ma 
    #结果显示为空,说明ma没有匹配到正确的结果
>>> ma = re.match(r'[A-Z][a-z]*', 'A') #匹配字符集[a-z]的0个或者无限个字符
>>> ma.group()
A
>>> ma = re.match(r'[A-Z][a-z]*', 'Abcdefg') #匹配字符集[a-z]的0个或者无限个字符
>>> ma.group()
Abcdefg
>>> 
  • + 匹配前一个字符1次或者无限次
>>> ma = re.match(r'[_a-zA-Z]+[\w]*', '_http123') #表示匹配前一个字符集中的字符1次或者无限次,后一个字符集中的字符0次或者无限次
>>> ma.group()
_http123
  • ? 匹配前一个字符0次或者1次
>>> ma = re.match(r'[1-9]?[0-9]', '90')
>>> ma.group()
90
>>> ma = re.match(r'[1-9]?[0-9]', '09')
>>> ma.group()
0
  • {m} / {m,n} 匹配前一个字符m次或者m到n次
 #可以用来匹配一个有效的邮箱
    >>> ma = re.match(r'[a-zA-Z0-9]{6}', 'ABC123') #表示出现字符集中的字符必须6次
>>> ma.group()
abc123
>>> ma = re.match(r'[a-zA-Z0-9]{6}', 'ABC12')
>>> ma
    #结果显示为空,说明ma没有匹配到正确的结果
>>> ma = re.match(r'[a-zA-Z0-9]{6}@qq.com', 'abc123@qq.com')
>>> ma.group()
abc123@qq.com
>>> ma = re.match(r'[a-zA-Z0-9]{6,10}@qq.com', 'abcd1234@qq.com') #出现字符集中的字符6到10次
>>> ma.group()
abcd1234@qq.com
  • *? / +? / ?? 匹配模式为非贪婪模式(尽可能少匹配字符)
>>> ma = re.match(r'[0-9][a-z]*', '2ba')
>>> ma.group()
2ba
>>> ma = re.match(r'[0-9][a-z]*?', '2ba')
>>> ma.group()
2
  • 边界匹配 ^ (匹配字符串的开头)$(匹配字符串的结尾)
#匹配一个邮箱
>>> ma = re.match('[\w]{4,10}@163.com', 'bobo@163.com')
>>> ma.group()
'bobo@163.com'
>>> ma = re.match('[\w]{4,10}@163.com', 'bobo@163.comabc')
>>> ma.group()
'bobo@163.com' #邮箱是不合法的,但是被匹配上了,这个并不是期望的结果
#匹配必须以@163.com结尾
>>> ma = re.match('[\w]{4,10}@163.com$', 'bobo@163.com')
  • \A \Z 指定的字符串必须出现在开头或者结尾
ma = re.match('\Abobo[\w]*', 'bobopython')
  • | 匹配或运算符左右的表达式
#匹配0-100的数字:0-99或100
>>> ma = re.match(r'[1-9]?\d$|100', '99')
>>> ma.group()
99
>>> ma = re.match(r'[1-9]?\d$|100', '100')
>>> ma.group()
100
  • (ab) 括号中的表达式作为一个分组
#需要匹配163或者126的邮箱
>>> ma = re.match(r'[\w]{4,6}@(163|126).com', 'bobo@126.com')
  • \<数字> 引用编号为’数字’的分组所匹配到的字符串

  • (?P<名字>) 分组起一个别名

  • (?P=名字) 引用别名为’名字’的分组所匹配到的字符串
    当存在多个引用的时候,使用别名的方式更加方便,可读性更强

re模块的其他方法

  • search(pattern, string, flags = 0)
    在一个字符串中查找匹配
  • findall(pattern, string, flags = 0)
    找到匹配,返回所有匹配部分的列表
>>> import re
>>> str1 = 'bobo videonum = 1000'
# 寻找字符串中的数字
>>> info = re.search(r'\d+', str1)
>>> info.group()
1000
>>> str2 = 'c++ = 100, java = 90, python = 80'
# 统计字符串中所有相关的数值
>>> info = re.search(r'\d+', str2)
>>> info.group()
100
#我们需要查找所有的数值,这个不是我们希望的结果
>>> info = re.findall(r'\d+', str2)
>>> info
['100','90', '80']
#求取列表中数字的和
>>> sum([int(x) for x in info])
270
  • sub(pattern, repl, string, count=0, flags=0)
    将字符串中匹配的正则表达式的部分替换成其他值
    参数repl:
    1. 如果是字符串的时候可直接进行替换。
    2. 如果函数的话,sub()会先匹配string,然后把匹配到的内容返回给repl,然后由repl函数接收,并在函数中处理接收到的数据
str3 = 'bobo videonum = 1000'
>>> info = re.sub(r'\d+', '1001', str3)
>>> info
'bobo video = 1001'

#使用一次正则表达式数字部分+1
>>> def add1(match):
        val = match.group()
        # 强制转换成数字之后+1
        num = int(val) + 1 
        return
>>> re.sub(r'\d+', add1, str3)
'bobo video = 1001'
  • split(pattern, string, maxsplit=0, flags=0)
    根据匹配分割字符串,返回分割字符串组成的列表
>>> str4 = 'class:C C++ Java Python'
# 分隔符包括冒号和空格
>>> re.split(r':| ', str4)
['class', 'C', 'C++', 'Java', 'Python']
# 分隔符包括冒号,空格和逗号
>>> str5 = 'class:C C++ Java Python,C#'
>>> re.split(r':| |,', str5)
['class', 'C', 'C++', 'Java', 'Python', 'C#']

利用正则表达式抓取网页内容

思路:
1. 抓取网页
2. 获取图片地址
3. 抓取图片内容并且保存到本地

>>> import urllib2
>>> import re
# 请求后台网站的网页
>>> req = urllib2.urlopen('http://www.imooc.com/course/list')
# 读取内容,缓存到buf中
>>> buf = req.read()
# 匹配以http开头和以jpg结尾的字符串所组成的图片地址
>>> listurl = re.findall(r'http:.+\.jpg', buf)
>>> i= 0
>>> for url in listurl:
    f = open(str(i)+'.jpg', 'w')
    req = urllib2.urlopen(url)
    buf = req.read()
    f.write(buf)
    i += 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值