python_正则表达式

正则表达式

描述了一种字符串匹配的模式(pattern),可以用来检查一个字符串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。


  1. 可以通过正则表达式来查找和检索文档中的特定文本
  2. 可以通过正则表达式来替换文本或删除文本
  3. 可以基于正则表达式从字符串中提取子字符串

Re

Python提供re模块,包含所有正则表达式的功能。

    import re

常用函数

一. match函数

    re.match(pattern, string, flags=0)
    
pattern	匹配的正则表达式
string	要匹配的字符串
flags	标志位, 正则表达式修饰符

  • 从头开始匹配, 匹配成功,返回一个Match对象,否则返回None
  • 只匹配一次,找到匹配结果则不进行继续匹配
  • 使用group()/group(0)获得匹配到的结果
  • 使用span()可以获取到匹配结果的下标区间
  • 如果需要分组获取匹配结果, 可以使用括号,并指定group(1)/group(2)等获得对应分组结果
  • groups()表示获取所有分组结果并以元组返回

练习
  • 判断网址’www.runoob.com’里面是否以’www’开头

    从头匹配,符合返回匹配对象

    str = ‘www.runoob.com
    pattern = ‘www’
    res = re.match(pattern,str)
    print(res)
    “”"<_sre.SRE_Match object; span=(0, 3), match=‘www’>"""

    从头匹配,不符合返回none

    str2 = ‘www.runoob.com
    pattern = ‘runoob’
    res = re.match(pattern,str2)
    print(res)
    “”“None”""

    只匹配一次

    str3 = ‘wwwwww.runoob.com
    pattern = ‘www’
    res = re.match(pattern,str3)
    “”"<_sre.SRE_Match object; span=(0, 3), match=‘www’>"""

    print(res.group())
    print(res.group(0))

    获取部分/分组匹配结果

    str2 = ‘runoob.com
    pattern = ‘(run)(oob)’
    res = re.match(pattern,str2)
    print(res.group())
    print(res.group(1))
    print(res.group(2))
    print(res.groups())

练习
str = """<div>我是一个人</div>"""
str1 = """<div>你好世界</div><div>我是一个人</div>"""
str2 = """<div>我是一个人</div><div>我是一个人</div>"""
pattern = '<div>我是一个人</div>'
res = re.match(pattern,str)


匹配模式

  • 点: \n除外的任意一个字符

  • 加号: 匹配1次或多次

  • 星号: 匹配0次或多次

    判断str是否含有子串’i’,并且是以其开头

    str = ‘i love you’
    pattern = ‘i’
    res = re.match(pattern,str)
    print(res)

    任意一个字符

    str = ‘i love you’
    str = ‘l love you’
    str = ‘\n love you’
    str = ‘we love you’
    str = ‘anyone love you’
    pattern = ‘i love you’
    pattern2 = ‘. love you’
    pattern3 = ‘.+ love you’
    pattern4 = ‘.* love you’
    res = re.match(pattern,str)
    print(res)

    text = “Cats are smarter than dogs”
    text = “”“

    你好世界
    我是一个人
    ”""
    text = ‘我和你’ #(.?)


贪婪模式与非贪婪模式

# 贪婪模式与非贪婪模式
str = 'howareyouhowareyou'
# .*   .*?
pattern = 'how.*you'
pattern1 = 'how.*?you'
# .+   .+?
pattern2 = 'how.+are'
pattern3 = 'how.+?are'

res = re.match(pattern,str)
res1 = re.match(pattern1,str)
res2 = re.match(pattern2,str)
res3 = re.match(pattern3,str)
print(res)
print(res1)
print(res2)
print(res3)

# .   .?
text = '我和你'
text = '我和和和你'
text = '我你'
pattern = '我.你'
text = '我和你'
text = '我和和和你'
text = '我你'
pattern = '我.?你'

注意

"""
.	匹配任意一个除了\n以外的字符
.*  匹配任意除了\n以外,0次到多次的字符, 默认贪婪模式
.+ 	匹配任意除了\n以外,1次到多次的字符, 默认贪婪模式
.?  匹配任意除了\n以外,0次到1次
.*? 匹配任意除了\n以外,0次到多次的字符, 默认非贪婪模式
.+? 匹配任意除了\n以外,1次到多次的字符, 默认非贪婪模式
"""

二. search函数

re.search(pattern, string, flags=0) 

pattern	匹配的正则表达式
string	要匹配的字符串。
flags	标志位, 正则表达式修饰符 - 可选标志
  • 从任意位置匹配,直到结束,匹配成功,返回匹配对象,否则返回None
  • 只匹配一次, 匹配成功即结束匹配
  • 使用group()/group(0)获得匹配到的结果
  • 使用span()可以获取到匹配结果的下标区间
  • 如果需要分组获取匹配结果, 可以使用括号,并指定group(1)/group(2)等获得对应分组结果
  • groups()表示获取所有分组结果并以元组返回
a = 'www.runoob.com'
print(re.search('www', 'www.runoob.com').span()) 
print(re.search('runoob', 'www.runoob.com').span()) 

a = """<div>我是一个人</div>"""
b = """<div>你好世界</div><div>我是一个人</div>"""
c = """<div>我是一个人</div><div>我是一个人</div>"""

match() 和search() 的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;
而re.search匹配整个字符串,直到找到一个匹配,没有匹配到返回None

匹配模式

^ 以指定字符开头

a = 'i love you'
a = 'do i love you'
pattern = '^i love you'

$ 以指定字符结尾

text = 'i love you'
text = 'i love you,too'
pattern = 'i love you$'


或 |

text = 'sss'
text = '127'
text = '127sss'
pattern = 'sss|127' 

res = re.search(pattern, text)
print(res.group())

[ ]

pattern = '[0-9]'
pattern = '[0-9]+'
text = '120293'

- [0-9] == [0123456789]
- [a-c] == [abc]
- [ABC] == [A-C]

^ 非

text = '123dfjsb'
pattern = '[^1]'    
pattern = '[^2]'    
pattern = '[^2]*'    
pattern = '[^1]*'    
pattern = '[^1]+'    

[ \f\r\t\n ]

匹配所有空白字符
换页 回车 制表符 换行 

re{n, m}

	匹配 n 到 m 次由前面的正则表达式定义的片段,默认贪婪

re{n,}

匹配至少n 个
pattern = 'o{2,}'
text = 'Bob'
text = "foooood"

"o{1,}" == "o+"
"o{0,}" == "o*"

re{n}

    固定匹配次数

注意

鼓励大家记住并使用 *、+ 和 ?,因为这些字符更短并且更容易阅读, 还有一个原因是匹配引擎对 * + ? 做了优化,效率要更高些 

特殊字符类

\d

匹配任意一个数字, 等价于[0-9]

pattern = '\d'
pattern = '\d\d'
pattern = '^f\d*'
pattern = '^\d+'    

\D

    匹配任意一个非数字, 等价于 [^0-9]

\s

    匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]


patttern = '\s+'
patttern = '\S+'
text = '       dwiefhew    dwehfiow  ehfdiewhfw '
res = re.search(patttern, text)
res = re.match(patttern, text)

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]

\w

匹配数字字母下划线。等价于'[A-Za-z0-9_]'

\W

匹配任何非数字字母下划线。等价于 '[^A-Za-z0-9_]'

修饰符(大写)

re.S : 使 . 匹配包括换行在内的所有字符

text = 'women\n'
pattern = 'women.'
res = re.search(pattern,text, re.S)


re.I : 使匹配对大小写不敏感

text = 'woMEn'
pattern = 'women'
res = re.search(parttern,text,re.I)


练习

1. 表单的邮箱验证

用户输入邮箱进行表单验证, 最多错五次, 如果5次内没有输入正确, 提示邮箱锁定

# text = input('请输入你的邮箱:')
pattern = '^[0-9a-zA-Z_]+@[0-9a-zA-Z_]+\.com$'
    
# if re.search(pattern, text):
#     print('邮箱格式正确~~~~')
# else:
#     print('什么破邮箱!!!!!')

2.【多选】
正则表达式A*B可以匹配
a. A
b. ACD
c. AB
d. AAB

3.【单选】
关于正则表达式,下列说法正确的是:
a. \w用来匹配数字
b. a?表示匹配0到多个a
c. re.I修饰符表示忽略大小写

3.【多选】
以下哪个字符串不能被正则表达式 a(bc?)d 匹配到? 
a. abcd
b. abd
c. abc
d. acd


常用函数

findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表

match 和 search 是匹配一次   findall 匹配所有

a = 'djwh0jwdhw0dwjbed0'
a = 'djwhjwdhwdwjbed'
res = re.findall('[a-z]+',a)

finditer()

在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回

text = 'i want to go home'
pattern = '[a-z]+'
res = re.finditer(pattern,text)
for i in res:
    print(i.group())

compile()

可以将模式单独定义, 大数据量时可以提高性能

reg = re.compile(pattern)
res = reg.search(text)


lines = [
'i wang to eat ',
'i wang to eat ',
'i wang to eat ',
'i wang to eat ',
]
for i in lines:
    res = re.search('[a-z]+]',i).group()
    print(res)

reg = re.compile('[a-z+]]')
for i in lines:
    res = reg.search(i).group()
    print(res)

sub()

re.sub(pattern, repl, string)

  • pattern : 被替换的正则表达式

  • repl : 替换字符串

  • string : 被替换的原始字符串

    text = ‘i love you’
    res = re.sub(‘love’, ‘not love’, text)
    print(res)


练习

将以下电话号码处理成纯数字

str = "2004-959-559 # 这是一个国外电话号码"

# 删除字符串中的 Python注释
res = re.sub('#.*$','',str)
res = re.sub('-','',res)
print(res)

# 或
res = re.sub('[^\d]+','',str)
print(res)

# 或
res = re.sub('\D+','',str)


# 爬虫中经常会用到sub来去除响应正文中的空白字符
text = 'xdjsh    dweuhfwuei  euwegf ub ue cudbcu'
res = re.sub('\s+', '', text)
print(res)

元字符

大多数字母和字符会匹配它们自身, 有少数特殊的字符我们称之为元字符(metacharacter),它们并不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等特殊功能


元字符

. ^ $ * + ? { } [ ] | ( )

转义

反斜杠 \

如果在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”不会被触发。例如你需要匹配符号 [ 或 \,你可以在它们前面加上一个反斜杠,以消除它们的特殊功能

s = '.   ^   $   *   +   ?   { }   [ ]   \   |   ( )'

res = re.findall('\$', s)
res = re.findall('\.', s)
res = re.findall('\( \)', s)
res = re.findall('\[ \]', s)

练习题

匹配一行文字中的所有开头的字母内容

s="i love you not because of who you are, but because of who i am when i am with you"

提取出所有副词

text = "He was carefully disguised but captured quickly by police."


pattern = '([a-zA-Z-])[a-zA-Z-]*'
pattern = '[a-zA-Z]+ly'

爬虫练习

百姓网


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值