Python基础语法:正则表达式

Python基础语法:正则表达式

概念:

从大量的信息中,通过一些表达式提取我们关注的数据。正则表达式就是其中一种进行数据筛选的表达式。

1. 原子:

原子是正则表达式中最基本的组成单位,每个正则表达式至少要包含一个原子,常见的原子类型有:

  1. 普通字符作为原子

    import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
    string="I like Python"
    pat="like"
    #正则表达式函数
    rst=re.search(pat,string) # search(想要搜索的内容,搜索来源的内容)
    print(rst)
    
  2. 非打印字符作为原子

    import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
    # 非打印字符作为原子
    #\n 换行符  \t   制表符
    string='''I like Python
    anaconda
    ''' # 三个引号中间可以引入换行的内容
    pat="\n"
    rst=re.search(pat,string)
    print(rst)
    
  3. 通用字符作为原子(比如十进制的数)

    import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
    #通用字符作为原子
    '''
    字符	字符代表的含义
    \w 	  字母、数字、下划线
    \W    除字母、数字、下划线
    \d    十进制数字
    \D    除十进制数字
    \s    空白字符
    \S    除空白字符
    '''
    string='''I like19 6172 Python'''
    pat="\w\d\s\d\d"
    rst=re.search(pat,string)
    print(rst)
    
  4. 原子表

    import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
    #原子表
    '''
    []表示,匹配时,从[]里面的选择一个内容即可,里面的原子地位是平等的。
    []里面有 ^ 符号时,表示除 [] 里面的原子都要提取
    '''
    string='''I like Python'''
    #pat="li[kgjd]e"
    pat="li[^abc]e"
    rst=re.search(pat,string)
    print(rst)
    

    正则表达式之原子匹配

2. 元字符

就是正则表达式中具有一些特殊含义的字符,比如连续重复N次的字符。

import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的

#元字符
'''
元字符       代表的内容
. 		    除换行外任意一个字符
^ 		    匹配开始位置
$ 		    匹配结束位置
* 		    前面原子出现 0\1\多次 
? 		    前面原子出现 0\1次
+ 		    前面原子刚好出现 1\多次
{n} 	    前面原子出现恰好     n 次
{n,} 	    前面原子出现至少 n 次
{n,m} 	    前面原子出现至少n,至多m次 
| 		    模式选择符或
() 		    模式单元
'''
string='''Tragedy and delight, hand in hand.'''
pat1="Tra..."		# 匹配Tra后面接三个不为换行符的字符
pat2="^Tra..."		# 匹配以Tra 开头的后面接两个不为换行符的字符
pat3="han.$"		# 匹配以 han 加一个不为换行符的字符结尾
pat4="and.*"		# 匹配该语句前面出现 and 加一个不为换行符的字符,且这部分出现了 0\1\多次 
pat5="del +"		# 匹配该语句前面出现 del ,且del出现了 1\多次 
pat6="age{1,2}"		# 匹配该语句前面出现 age ,且这部分出现至少1次,至多2次 

rst1=re.search(pat1,string)
rst2=re.search(pat2,string)
rst3=re.search(pat3,string)
rst4=re.search(pat4,string)
rst5=re.search(pat5,string)
rst6=re.search(pat6,string)

print(rst1)
print(rst2)
print(rst3)
print(rst4)
print(rst4)
print(rst6)

注意:

  1. 末尾的 . 也算一个字符,所以 pat3 是匹配不上的。

  2. *、?、+ 匹配时不是匹配前面整个部分出现多少次,而是前面整个部分最后一个字符出现的次数。

    test* 	-- 可以匹配 tes、test、testt......
    test?  	-- 可以匹配 tes、test
    test+	-- 可以匹配 test、testt、testtt......
    

正则表达式之元字符

3. 模式修正符

即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些结果的调整等功能。

import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
#模式修正符
'''
模式修正符        代表含义   
    I            匹配时忽略大小写(重要)
    M            多行匹配(重要)
    L            本地化识别匹配
    U            unicode
    S            让.匹配包括换行符(重要)
'''
string="Python"
pat="pyt"
rst=re.search(pat,string,re.I) # search(想要搜索的内容,搜索来源的内容,设置模式修正符(格式 re. 模式修正符))
print(rst)

正则表达式之模式修正符

4. 贪婪模式和懒惰模式

贪婪模式的核心点就是尽可能多的匹配,
懒惰模式的核心点就是尽可能少的匹配。

import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
#贪婪模式和懒惰模式
string="poythonyhjskjsa"
pat1="p.*y"		# 贪婪模式
pat2="p.*?y"	# 懒惰模式,精准
rst1=re.search(pat1,string,re.I)
rst2=re.search(pat2,string,re.I)
print(rst1)
print(rst2)

注意:

​ 在贪婪模式下,因为 * 前面是一个 . 符号,而 . 匹配除换行外任意一个字符,* 前面原子出现 0\1\多次,所以在这意为匹配任意个 不为换行符的字符 。

​ 懒惰模式格式中必有 ? ,在上面例子中 .*?表示以懒惰模式匹配.*

正则表达式之贪婪模式和懒惰模式

5. 正则表达式函数

match函数:从头开始匹配

search函数:随意在哪都可以开始匹配

全局匹配函数:只要符合正则表达式的,都会匹配出来,不会匹配完只出现一个结果
​ 全局匹配格式re.compile(正则表达式).findall(数据)

import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
#正则表达式函数
#1、match
string="poythonyhjskjsa"
pat="p.*?y" 	# 如果是 o.*?y 则匹配不到,为null
rst=re.match(pat,string,re.I)
print(rst)

正则表达式之正则表达式函数-match函数

import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
#3、全局匹配函数
string="hgpoythpnyhjsptjhgjykjsa"
pat="p.*?y"#懒惰模式,精准
#全局匹配格式re.compile(正则表达式).findall(数据)
rst=re.compile(pat).findall(string)
print(rst)

正则表达式之正则表达式函数-全局匹配函数

6. 实例

  1. 匹配.com和.cn网址

    import re # 要想使用正则表达式,就要导入这个模块,这个模块时系统自带的
    #实例:匹配.com和.cn网址
    string="<a href='http://www.baidu.com'>百度首页</a>'"
    pat="[a-zA-Z]+://[\S]+[.com|.cn]"
    rst=re.compile(pat).findall(string)
    print(rst)
    

    解析:因为要匹配网址,网址的格式有很多种,比如ftp开头的、http开头的、https开头的…

    为了匹配这个开头的协议:我们先使用一个原子表来匹配,中间放上英文字母 [a-zA-Z],因为这个长度不定,所以使用元字符 + 号来匹配出现一次或者多次。

    接着就是固定格式:// ,所以接上这个。

    后面是域名,域名这个长度不定,可以数字、也可以是字符、还可以是符号,但是中间应该没有空格(域名中间有空格的还真没印象),所以这个使用\S

    因为域名的长度不定,所以使用元字符 + 号来匹配出现一次或者多次。

    接下来的结尾分两种 .com.cn,对于这两种,我们使用元字符中的模式选择符来实现,所以为[.com|.cn]

    综合起来就是:[a-zA-Z]+://[\S]+[.com|.cn]

    正则表达式案例之获取url

  2. 匹配电话号码

    #实例:匹配电话号码
    string="jsghajsdhk021-8928874997678328jhdjskgjkh0773-776257672360kjcxdhkj"
    pat="\d{4}-\d{7}|\d{3}-\d{8}"
    rst=re.compile(pat).findall(string)
    print(rst)
    

    解析:电话号码格式有xxx-xxxxxxxxxxxx-xxxxxxx两种,所以我们用元字符中的模式选择符来实现。

    又因为电话号码都是数字,所以我们使用通用符作为原子,即使用 \d 表示十进制数。

    按照上面的格式,可以表示为:\d{4}-\d{7}|\d{3}-\d{8}

正则表达式案例之获取电话号码

7. 简单爬虫

直接使用系统自带的urllib库来编写。

案例:爬 CSDN 首页的url

#简单爬虫的编写
import urllib.request
data=urllib.request.urlopen("http://edu.csdn.net").read()
print(data)

简单爬虫爬CSDN首页

ps:这个爬取出来是页面的HTML文件。

案例:自动提取课程页面的QQ群

#自动提取课程页面的QQ群
import urllib.request
import re
data=urllib.request.urlopen("http://edu.csdn.net/huiyiCourse/detail/253").read().decode("utf-8")
pat="<p>(\d*?)</p>"
rst=re.compile(pat).findall(data)
print(rst)

注意:这里有两个细节点:

  1. decode("utf-8") :urllib读取过来的是二进制文件,需要进行转码,utf-8格式是中文格式,也是常用的格式。
  2. 正则表达式中的小括号:如果不加这小括号则输出的是整个正则表达式匹配到的数据,如果加上小括号,则输出的是小括号里面的内容。
    自动提取课程页面的QQ群

最后:页面都是实时的变化的,可能今天可以用这段代码去提取,但是过了一阵子可能就提取不出来了,我这边按照学习视频里的就不行了,最后需要自己修改才行,所以学习是死的,灵活运用才是真的。

猜你喜欢

转载自blog.csdn.net/xxydzyr/article/details/86562857