Python中使用正则表达式

第1章 正则表达式基本概念

  1. 字符串匹配可以完成,但是每次匹配,都要单独写一次代码来完成,正则表达式是字符串匹配方法的抽象规则,可以简单的复用。
  2. 使用单个字符串来描述匹配一系列符合某个语法规则的字符串。
  3. 对字符串操作的一种逻辑公式。
  4. 应用场景:处理文本和数据
  5. 正则表达式的过程:依次拿出表达式与文本中的字符串进行比较,如果每一个字符都能匹配,则匹配成功;否则匹配失败。

第2章 正则表达式re模块

  1. re模块的标准匹配方法


  2. re模块匹配的实例


  3. re模块匹配的简单用法


备注:标准匹配方法,是提前生成了Pattern对象,可以反复使用,以提高代码效率,特别是代码中有大量的正则匹配时;使用简单匹配方法,每次都要生成一个Pattern对象,正则匹配不多时,该方法比较简单。

  1. 说明
  • 正则表达式中,通常在字符串前加r表示该字符串为原字符串,即不需要对特殊字符进行转义。
  • match():从字符串的开始位置进行匹配
  • compile(): 可以增加忽略大小写的参数,如:re.compile(r'imooc', re.I),在进行正则匹配时,可以忽略大小写进行匹配

第3章 正则表达式语法

一、单字符匹配语法

字符 匹配
. 匹配除了 “\n” 以外的任意一个字符
[...] 匹配字符集中的任意一个字符
\d、\D 匹配任意一个数字、任意一个非数字
\s、\S 匹配一个空白、一个非空白字符
\w、\W 匹配[a-zA-Z0-9]之间的单字符、[a-zA-Z0-9]以外的单字符
  1. (.)示例
ma = re.match(r'.', 'a')
ma.group() 
--> 'a'

ma = re.match(r'.', 'abc')    #多个字符时,只匹配到第一个字符
ma.group() 
--> 'a'

ma = re.match(r'{.}', '{a}') 
ma.group()
--> 'a'

ma = re.match(r'{.}', '{abc}')    # 带花括号,多个字符时会报错
ma.group()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 in ()
----> 1 ma.group()
AttributeError: 'NoneType' object has no attribute 'group'
  1. [...]\w\W示例
ma = re.match(r'[abcd]', 'c')
ma.group() 
--> 'c'

ma = re.match(r'[abcd]', 'dc')    # 仅匹配第一个字符
ma.group() 
--> 'd'

ma = re.match(r'[abcd]', 'ec')    # 第一个字符匹配不到时,返回错误
ma.group() 
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 in ()
----> 1 ma.group()
AttributeError: 'NoneType' object has no attribute 'group'

ma = re.match(r'[a-zA-Z0-9]', 'X')    # 正则表达式中,表示字符集的方法:a-zA-Z0-9. 该示例,其实可以使用正则语法 ‘\w’ 的简单写法
ma.group() 
--> 'X'

ma = re.match(r'\w', 'X')    # 结果同上面所示的例子。‘\w’匹配单字符 [a-zA-Z0-9]
ma.group() 
--> 'X'

ma = re.match(r'\W', '@')    #‘\W’ 匹配 [a-zA-Z0-9]以外的单字符
ma.group() 
--> 'X'

ma = re.match(r'\[[\w]\]', '[X]')    # 匹配中括号中内容时,需要先对中括号进行转义
ma.group() 
--> '[X]'
  1. \s\S\d\D示例
ma = re.match(r'\d', '9')    # 匹配任意一个数字
ma.group() 
-- > '9'

ma = re.match(r'\D', '$')    # 匹配任意一个非数字
ma.group() 
-- > '$'

ma = re.match(r'\s', ' ')    # 匹配一个空白
ma.group() 
-- > ' '

ma = re.match(r'\S', '#')    # 匹配任意一个非空白
ma.group() 
-- > '#'

二、多字符匹配语法

字符 匹配
* 匹配前一个字符0次或无限次
+ 匹配前一个字符1次或无限次
匹配前一个字符0次或1次
{m}、{m, n} 匹配前一个字符m次或n次
*?、+?、?? 匹配模式变为非贪婪,即尽可能少的匹配
  1. 星号(*)示例
ma = re.match(r'[A-Z][a-z]*', 'Asbdjfjf')  # 匹配一个大写字母后所有的小写字母
ma.group() 
-- > 'Asbdjfjf'

ma = re.match(r'[A-Z][a-z]*', 'F')  # 若前一个字符后没有小写字母也可以,即匹配0次
ma.group() 
-- > 'F'
  1. 加号(+)示例
ma = re.match(r'[_a-zA-Z]+[_\w]*', 'overdue_day')  # 匹配一个有效的python变量名称:必须是以下划线或大小写字母开头
ma.group() 
-- > 'overdue_day'

ma = re.match(r'[0-9][\w]+','1')  # 加号(+)必须要匹配前一个字符1次或无限次,不存在时会报错
ma.group() 
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 in ()
----> 1 ma.group()
AttributeError: 'NoneType' object has no attribute 'group'
  1. 问号(?)示例
ma = re.match(r'[1-9]?[0-9]', '90')  # 匹配 0-99之间的数字
ma.group() 
-- > '99'

ma = re.match(r'[1-9]?[0-9]', '09')  # 不报错,但是第一位匹配不到,第二位为0
ma.group() 
-- > '0'
  1. {m} / {m,n}示例
ma = re.match(r'[a-zA-Z0-9]{6,10}@163.com', '[email protected]')  # 出现的字符少时返回空,出现的字符多时,仅匹配到指定的位数
ma.group() 
-- > '[email protected]'
  1. *?、+?、??示例
ma = re.match(r'[1-9][\w]*?', '1ab')  # *? 尽可能少的匹配,即不匹配
ma.group() 
-- > '1'

ma = re.match(r'[1-9][\w]+?', '1ab')  # +? 尽可能少的匹配,即仅匹配1次
ma.group() 
-- > '1a'

ma = re.match(r'[1-9][\w]??', '1ab')  # ?? 尽可能少的匹配,即不匹配
ma.group() 
-- > '1'

三、边界匹配语法

字符 匹配
^ 匹配字符串开头
$ 匹配字符串结尾
\A、\Z 指定的字符串必须出现在开头、结尾
  1. ^$示例
ma = re.match(r'[a-zA-Z0-9]{6,10}@163.com', '[email protected]')  # 可以匹配到邮箱地址,但不是一个有效的邮箱地址
ma.group()
-- > '[email protected]'

ma = re.match(r'[a-zA-Z0-9]{6,10}@163.com$', '[email protected]')  # 在结尾加上`$`即可限制匹配,得到合法的邮箱地址。^的使用方法相同
ma.group()
-- > '[email protected]'
  1. \A\Z示例
ma = re.match(r'\Apython[\w]*', 'python123learning')  # 匹配以 python 开头的字符串。\Z的使用方法相同
ma.group()
-- > 'python123learning'

四、分组匹配语法

字符 匹配
| 匹配左右任意一个表达式
() 括号中表达式作为一个分组
\number 重复第number个分组的匹配
(?P) 分组起一个别名
(?P=name>) 重复别名为name的分组的匹配
  1. \|示例
ma = re.match(r'\Apython[\d]|[\S]*', 'python3')   # 匹配python开头加1个数字或任意个非空字符
ma.group()
-- > 'python3'

ma = re.match(r'\Apython[\d]|[\S]*', 'python_learnning') 
ma.group()
-- > 'python_learnning'

ma = re.match(r'[1-9]?[\d]$|100', '100')  匹配0-100之间的数字
ma.group()
-- > '100'
  1. ()示例
ma = re.match(r'[\w]{5,15}@(163|qq|126).com$', '[email protected]')   # 括号中用或(|)符号隔开分组

ma.group()
-- > '[email protected]'

ma.groups()  # groups()方法可以输出 分组()所匹配到的字符串
-- > ('126',)
  1. \number: 重复第number个分组()的匹配,即该分组匹配2次。
ma = re.match(r'[\w](python)[\d](_)\1\2[\d]', 'ipython2_python_3')  # ‘\1’重复第一个分组(python)的匹配、‘\2’重复第二个分组(_)的匹配

ma.group()
-- > 'ipython2_python_3'

ma.groups() 
-- > ('python', '_')
  1. (?P)(?P=name>)示例
# 第一个分组别名Language、第二个分组别名sign
ma = re.match(r'[\w](?Ppython)[\d](?P_)(?P=Language)(?P=sign)[\d]', 'ipython2_python_3')  

ma.group()
-- > 'ipython2_python_3'

ma.groups() 
-- > ('python', '_')


第4章 re模块相关的使用方法

一、查找函数简介

  1. match(pattern, string, flags=0):从字符串的首字母开始匹配,包含pattern子串,则匹配成功,返回Match对象,失败则返回None。若要完全匹配,则pattern要以$结尾;
  2. search(pattern, string, flags=0): 在字符串中查找,若string中包含pattern子串,则返回Match对象,否则返回None。若string中存在多个pattern子串,只返回第一个;
    str1 = 'python_video_num = 1000'
    se = re.search(r'\d+', str1)
    se.group()
    -- > '1000' 
    
  3. findall(pattern, string, flags=0):在字符串中查找,返回string中所有与pattern匹配的子串组成的列表,匹配不到时返回空列表;
    str2 = 'C++ = 100, Java = 90, Python = 80'
    fa = re.findall(r'\d+', str2)
    fa
    -- > ['100', '90', '80']
    

二、替换分割函数简介

  1. sub(pattern, repl, string, count=0, flags=0): 将字符串中匹配正则表达式的部分替换为指定的字符串。repl是字符串或函数返回的字符串;count是替换次数,忽略时表示全部替换。
    str3 = 'python_learnning count = 900'  # 将数字900替换成200
    su = re.sub(r'\d+', '200', str3)
    su
    -- > 'python_learnning count = 200'
    
    # 定义一个数字加100的函数,传入的对象是Match对象
    def add(match):
        item = match.group()
        term = int(item) + 100
        return str(term)
    
    sb = re.sub(r'\d+', add, str3)  #数字加100
    sb
    -- > 'python_learnning count = 1000'
    
  2. split(pattern, string, maxsplit=0, flags=0): 根据匹配的分割字符串进行分割,返回分割后各部分字符串组成的列表。maxsplit是分割的次数,默认全部分割。
    str4 = 'Course:C++ Java Python,C#'  # 分割字符串有3个:冒号(:)、空格( ) 和 逗号(,)
    sp = re.split(r':| |,', str4)
    sp
    -- > ['Course', 'C++', 'Java', 'Python', 'C#']
    


第5章 练习——抓取网页中的图片到本地

  1. 抓取网页
import re
import requests

url = 'https://www.imooc.com/course/list'
r = requests.get(url)
content = r.text    # content即为网页内容
  1. 获取图片地址
url_list = re.findall(r'src=.+\.jpg', content)  # 正则表达式匹配图片的地址(相对路径)

url_list
['src="//img1.mukewang.com/529dc3380001379906000338-240-135.jpg',
 'src="//img.mukewang.com/57035ff200014b8a06000338-240-135.jpg',
 'src="//img1.mukewang.com/574669dc0001993606000338-240-135.jpg',
 'src="//img.mukewang.com/53e1d0470001ad1e06000338-240-135.jpg',
 'src="//img4.mukewang.com/540e57300001d6d906000338-240-135.jpg',
 'src="//img1.mukewang.com/53a28e960001311b06000338-240-135.jpg',
 'src="//img.mukewang.com/5bd01cf40001666806000338-240-135.jpg',
 'src="//img1.mukewang.com/5bbf2def000118ab06000336-240-135.jpg',
 'src="//img4.mukewang.com/5bc0879f0001852905400300-240-135.jpg',
 'src="//img4.mukewang.com/5bc8201500017bb306000338-240-135.jpg',
 'src="//img1.mukewang.com/5bc6e6b80001434f06000338-240-135.jpg',
 'src="//img1.mukewang.com/5bc552390001884602400135-240-135.jpg',
 'src="//img.mukewang.com/5bc44d080001049906000338-240-135.jpg',
 'src="//img.mukewang.com/5bbabc240001d88e05400300-240-135.jpg',
 'src="//img1.mukewang.com/5bbc52f60001d1be06000338-240-135.jpg',
 'src="//img2.mukewang.com/5bbafd180001688d06000338-240-135.jpg',
 'src="//img1.mukewang.com/5b9a01a40001fe1805400300-240-135.jpg',
 'src="//img2.mukewang.com/5badc2980001ca6d06000338-240-135.jpg',
 'src="//img2.mukewang.com/5b9b4f6b0001130205400300-240-135.jpg',
 'src="//img.mukewang.com/5ba2386600013d3705980337-240-135.jpg',
 'src="//img1.mukewang.com/5ba0569c00010a4605400300-240-135.jpg',
 'src="//img3.mukewang.com/5b9f578c00011ee106000338-240-135.jpg',
 'src="//img3.mukewang.com/5b9f24bb0001fb3706000338-240-135.jpg',
 'src="//img1.mukewang.com/5b5d5b760001dd9506000338-240-135.jpg',
 'src="//img3.mukewang.com/5b69142c0001d10705400300-240-135.jpg',
 'src="//img3.mukewang.com/5b9105800001288905400300-240-135.jpg',
 'src="//img.mukewang.com/5b8e323900017f7406000338-240-135.jpg',
 'src="//img1.mukewang.com/5b8ce427000121b406000338-240-135.jpg',
 'src="//img4.mukewang.com/5b88e7f90001104e06000338-240-135.jpg',
 'src="//img.mukewang.com/5b86566a0001d31106000338-240-135.jpg']

picture_url = [s.replace('src="', 'http:') for s in url_list]  # 将相对路径修改为绝对路径

picture_url
['http://img1.mukewang.com/529dc3380001379906000338-240-135.jpg',
 'http://img.mukewang.com/57035ff200014b8a06000338-240-135.jpg',
 'http://img1.mukewang.com/574669dc0001993606000338-240-135.jpg',
 'http://img.mukewang.com/53e1d0470001ad1e06000338-240-135.jpg',
 'http://img4.mukewang.com/540e57300001d6d906000338-240-135.jpg',
 'http://img1.mukewang.com/53a28e960001311b06000338-240-135.jpg',
 'http://img.mukewang.com/5bd01cf40001666806000338-240-135.jpg',
 'http://img1.mukewang.com/5bbf2def000118ab06000336-240-135.jpg',
 'http://img4.mukewang.com/5bc0879f0001852905400300-240-135.jpg',
 'http://img4.mukewang.com/5bc8201500017bb306000338-240-135.jpg',
 'http://img1.mukewang.com/5bc6e6b80001434f06000338-240-135.jpg',
 'http://img1.mukewang.com/5bc552390001884602400135-240-135.jpg',
 'http://img.mukewang.com/5bc44d080001049906000338-240-135.jpg',
 'http://img.mukewang.com/5bbabc240001d88e05400300-240-135.jpg',
 'http://img1.mukewang.com/5bbc52f60001d1be06000338-240-135.jpg',
 'http://img2.mukewang.com/5bbafd180001688d06000338-240-135.jpg',
 'http://img1.mukewang.com/5b9a01a40001fe1805400300-240-135.jpg',
 'http://img2.mukewang.com/5badc2980001ca6d06000338-240-135.jpg',
 'http://img2.mukewang.com/5b9b4f6b0001130205400300-240-135.jpg',
 'http://img.mukewang.com/5ba2386600013d3705980337-240-135.jpg',
 'http://img1.mukewang.com/5ba0569c00010a4605400300-240-135.jpg',
 'http://img3.mukewang.com/5b9f578c00011ee106000338-240-135.jpg',
 'http://img3.mukewang.com/5b9f24bb0001fb3706000338-240-135.jpg',
 'http://img1.mukewang.com/5b5d5b760001dd9506000338-240-135.jpg',
 'http://img3.mukewang.com/5b69142c0001d10705400300-240-135.jpg',
 'http://img3.mukewang.com/5b9105800001288905400300-240-135.jpg',
 'http://img.mukewang.com/5b8e323900017f7406000338-240-135.jpg',
 'http://img1.mukewang.com/5b8ce427000121b406000338-240-135.jpg',
 'http://img4.mukewang.com/5b88e7f90001104e06000338-240-135.jpg',
 'http://img.mukewang.com/5b86566a0001d31106000338-240-135.jpg']
  1. 抓取图片内容并保存本地
i = 0
for url in picture_url:
    f = open(str(i)+'.jpg', 'w')    # 创建文件,并为图片命名
    picture = requests.get(url)    # 获取图片
    f.write(picture.text)  #写入图片并保存
    i += 1
  1. 保存的图片


你可能感兴趣的:(Python中使用正则表达式)