python re正则表达式

作者: 清水秋香 | 来源:发表于2020-02-18 01:03 被阅读0次
match

从左至右匹配只要满足了就可以,若开头不满足返回None

#使用match方法进行匹配
result = re.match(正则表达式,要匹配的字符串)
#如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()

re.match 是用来进行正则匹配检查的方法,若字符串匹配正则表达式,则match方法返回匹配对象(match object),否则返回None(注意不是空字符串)
匹配对象Match object具有group方法,用来返回字符串的匹配部分
dir(result) 可打印出re.match所有的方法

import re
str_1 = 'hometest'
pattern = 'home'
result = re.match(pattern,str_1)
print(dir(result))
print(result.group())
#与字符串方法startswith()效果基本一致
print(str_1.startswith('home'))
  • group() 传入1表示第一个分组即第一个括号中的内容
>>> result = re.match('(<h1>).*(</h1>)','<h1>哈哈哈</h1>')
>>> result.group(1)
'<h1>'
>>> result.group(2)
'</h1>'
>>> result.group(0)
'<h1>哈哈哈</h1>'
>>> 
  • groups 可取出所有括号中的内容
>>> result = re.match('(<h1>).*(</h1>)','<h1>哈哈哈</h1>')
>>> result.groups()
('<h1>', '</h1>')
>>> result.groups()[0]
'<h1>'
>>> result.groups()[1]
'</h1>'
search

从头往后进行匹配,直到匹配到复合正则表达式的截止 search只要匹配到第一个符合条件的就结束就不会向后在检查了。

>>> s = 'haha<h1>heihei<h1>'
>>> r = re.search('\w+<h1>',s)
>>> r.group()
'haha<h1>'

>>> s = '<html><h1>haha</h1></ht>'
>>> re.search('haha',s)
<_sre.SRE_Match object; span=(10, 14), match='haha'>
在search中^  $ 会限定在s字符串中匹配开头字符为h,结尾字符为a
>>> re.search('^haha$',s)
>>> 
>>> s = 'haha</h1></ht>'
>>> re.search('^haha',s)
<_sre.SRE_Match object; span=(0, 4), match='haha'>
findall

会拿到所有符合条件的结果返回一个列表

>>> s = 'haha<h1>heihei<h1>'
>>> r = re.findall('\w+<h1>',s)
>>> r
['haha<h1>', 'heihei<h1>']
表示字符
  • . 匹配任意一个字符(除了\n)
>>> re.match('.','\n')
>>> re.match('..','ab')
<_sre.SRE_Match object; span=(0, 2), match='ab'>
>>> re.match('..','abc')
<_sre.SRE_Match object; span=(0, 2), match='ab'>
>>> re.match('..','a')
>>> 
  • \d 匹配数字即0-9
>>> re.match('\d','1')
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> re.match('\d','a')
>>> 
  • \D 匹配非数字,即不是数字
>>> re.match('\D','a')
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> re.match('\D','3')
>>> 
  • \s 匹配空白字符,即空格、tab 包括空白字符\r将光标移至首位 \t水平制表符 \n换行
>>> re.match('\s',' ')
<_sre.SRE_Match object; span=(0, 1), match=' '>
>>> re.match('\s','     ')
<_sre.SRE_Match object; span=(0, 1), match='\t'>
>>> re.match('\s','s')
>>> re.match('\s','1')
>>> 
<_sre.SRE_Match object; span=(0, 1), match='\n'>
>>> re.match('\s','\t')
<_sre.SRE_Match object; span=(0, 1), match='\t'>
>>> re.match('\s','\r')
<_sre.SRE_Match object; span=(0, 1), match='\r'>
  • \S 匹配非空格
>>> re.match('\S','\n')
>>> re.match('\S',' ')
>>> re.match('\S',' a')
>>> re.match('\S','\ta')
>>> re.match('\S','a')
<_sre.SRE_Match object; span=(0, 1), match='a'>

  • \w 单词字符即a-z | A-Z | 1-9 | - 数字 字母 下划线 变量名命名规则
>>> re.match('\w','-a')
>>> re.match('\w','\na')
>>> re.match('\w','_a')
<_sre.SRE_Match object; span=(0, 1), match='_'>
>>> re.match('\w','1a')
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> re.match('\w','a')
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> re.match('\w','A')
<_sre.SRE_Match object; span=(0, 1), match='A'>
  • \W 非单词字符 即不匹配数字 字母 下划线
>>> re.match('\W','\n')
<_sre.SRE_Match object; span=(0, 1), match='\n'>
>>> re.match('\W','1')
>>> re.match('\W','a')
>>> re.match('\W','_')
>>> re.match('\W','f-')
>>> 

#匹配规则为\w与1进行匹配,发现匹配,\W与a进行匹配发现不匹配所以返回None
>>> re.match('\w\W','1a')
>>> re.match('\w\W','1-')
<_sre.SRE_Match object; span=(0, 2), match='1-'>
  • [ ]匹配[ ]中列举的字符 方括号中不要出现逗号或者空格 [^ ] []中的^代表取反的意思 a-z 1-9 -代表范围
>>> re.match('1[234]','14')
<_sre.SRE_Match object; span=(0, 2), match='14'>
>>> re.match('1[234]','15')
>>> re.match('1[234]','25')
>>> re.match('1[234]','1w')
>>> 

[^ ] []中的^代表取反的意思
>>> re.match('1[^234]','12')
>>> re.match('1[^234]','13')
>>> re.match('1[^234]','15')
<_sre.SRE_Match object; span=(0, 2), match='15'>
>>>
#- 代表一个范围
>>> re.match('1[^a-z5-9]','15')
>>> re.match('1[^a-z5-9]','1a')
>>> re.match('1[^a-z5-9]','1A')
<_sre.SRE_Match object; span=(0, 2), match='1A'>
>>> 

\d = [0-9]
\D = [^0-9]
\w = [a-zA-Z0-9_]
\W = [^a-zA-Z0-9]

  • *匹配前一个字符出现0次或者无限次,即可有可无
\d*代表可以是数字也可以不是数字,所以都匹配
>>> re.match('\d*','dd')
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match('\d*','d2')
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match('\d*','|')
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match('\d*','_')
<_sre.SRE_Match object; span=(0, 0), match=''>

  • +匹配前一个字符出现一次或者无限次,至少有一次
>>> re.match('\d+','a')
>>> re.match('\d+','1')
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> re.match('3+','1')
>>> re.match('3+','31231')
<_sre.SRE_Match object; span=(0, 1), match='3'>
\d+[a-z] 可以匹配,因为\d+  效果为\d\d\d\d\d\d\d\d\d\d任意个\d出现
>>> re.match('\d+[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 7), match='3232323'>
  • ? 匹配前一个字符出现1次或者0次,即要么有一次,要么没有
>>> re.match('\d?','3232323g')
<_sre.SRE_Match object; span=(0, 1), match='3'>
>>> re.match('\d?','3232323g')
<_sre.SRE_Match object; span=(0, 1), match='3'>
>>> re.match('\d?','g')
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match('\d?','_')
<_sre.SRE_Match object; span=(0, 0), match=''>
  • {m}匹配前一个字符出现m次
>>> re.match('\d{5}[a-z]','3232323g')
>>> re.match('\d{7}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
  • {m,}匹配前一个字符出现m次及以上 {1,}等价+ {0,}等价*
>>> re.match('\d{5,}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
>>> re.match('\d{7,}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
>>> re.match('\d{8,}[a-z]','3232323g')
  • {m,n} 匹配前一个字符出现从m到n次
表示最少是3个最多是7个所以匹配
>>> re.match('\d{3,7}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
>>> re.match('\d{3,9}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
>>> re.match('\d{7,9}[a-z]','3232323g')
<_sre.SRE_Match object; span=(0, 8), match='3232323g'>
>>> re.match('\d{8,9}[a-z]','3232323g')
>>> 
>>> re.match('1[359]\d{9}','12444444444')
>>> re.match('1[359]\d{9}','13444444444')
<_sre.SRE_Match object; span=(0, 11), match='13444444444'>
>>> re.match('1[359]\d{9}','13444444444dddd')
<_sre.SRE_Match object; span=(0, 11), match='13444444444'>
#可见匹配为空字符串,a可以理解成"" + a 所有匹配到的是空字符串 \d*   前面的\d与a不是完全匹配,而前面的空字符串与 \d*完全匹配 
>>> re.match('\d*','a')
<_sre.SRE_Match object; span=(0, 0), match=''>
  • /转义


    反杠的困扰.jpg
因为\b 有两种解释,而\w 只有一种。
\b的两种解释是:
'\b', 如果前面不加r, 那么解释器认为是转义字符“退格键backspace”;
r'\b', 如果前面加r, 那么解释器不会进行转义,\b 解释为正则表达式模式中的字符串边界。
而相比于\b, \w 只有第二种解释,并没有对应的转义字符,所以不加r, 也不会出错。
>>> re.match(r'\\w','\w')
<_sre.SRE_Match object; span=(0, 2), match='\\w'>
>>> re.match(r'\\b','\\b')
<_sre.SRE_Match object; span=(0, 2), match='\\b'>


>>> print('\nabc')

abc
#理解成转义需要加\取消转义
>>> print('\\nabc')
\nabc
#匹配字符为\\nabc 想要成功匹配需要加两个/来进行转义才可匹配
>>> re.match('\\\\n\w','\\nabc')
<_sre.SRE_Match object; span=(0, 3), match='\\na'>
>>> re.match('\\n\w','\\nabc')
>>> 
  • r 原始格式raw的缩写,就是说输入的时候是什么样的在打印的时候就应该是什么样的
>>> >>> re.match(r'\\n\w','\\nabc')
<_sre.SRE_Match object; span=(0, 3), match='\\na'>
  • ^匹配字符串开头
>>> re.match('^1[345]\d{9}$','12942545378')
>>> re.match('^1[345]\d{9}$','13942545378')
<_sre.SRE_Match object; span=(0, 11), match='13942545378'>
>>> re.match('^1[345]\d{9}$','1394254537')
>>> 
>>> re.match('^1[345]\d{9}$','2394254537')
>>> 
  • $匹配字符串结尾
>>> re.match('^1[345]\d{9}$','12942545378')
>>> re.match('^1[345]\d{9}$','13942545378')
<_sre.SRE_Match object; span=(0, 11), match='13942545378'>
>>> re.match('^1[345]\d{9}$','1394254537')
>>> 
  • \b匹配一个单词的边界 $ ^ \b 只是描述边界信息 不包含字符本身
此例子用\b匹配ou的边界
加\s 因为\b只是描述边界信息不包含字符本身 
正则中一个杠匹配不到,因为文件中的反杠需要4个反杠来匹配
>>> re.match(r'\w\s\bou\b\s\w','h ou \w')
>>> re.match(r'\w\s\bou\b\s\\w','h ou \w')
<_sre.SRE_Match object; span=(0, 7), match='h ou \\w'>
  • \B匹配非单词边界
>>> re.match(r'[a-z]\s\bou\b\sr','d ou r')
<_sre.SRE_Match object; span=(0, 6), match='d ou r'>
>>> re.match(r'[a-z]\s\bou\B\sr','d ou r')
>>> 

>>> re.match(r'[a-z]\s\bou\Br','d our')
<_sre.SRE_Match object; span=(0, 5), match='d our'>
>>> 
  • | 匹配左右任意一个表达式
>>> re.match(r'^[1-9]\d?$|0$|100$','0')
<_sre.SRE_Match object; span=(0, 1), match='0'>
>>> re.match(r'^[1-9]\d?$|0$|100$','100')
<_sre.SRE_Match object; span=(0, 3), match='100'>
>>> 
  • (ab) 括号中的字符作为一个分组
group(1)表示表达式中的第一个分组,即第一组出现的括号
>>> result = re.match('<h1>(.*?)</h1>','<h1>哈哈哈</h1>')
>>> result.group(1)
'哈哈哈'
>>> 
  • \num 引用分组num匹配到的字符串

<html><h1>haha</h1></html>
让第一次出现的html在最后的html位置出现,第一次出现的h1在最后一次出现的h1位置出现,将内容忽略即第一次出现的内容在第二次出现的位置再次出现。

<html><h1>haha</h1></html>
\2代表第一个括号出现的位置 即第一次出现的h1     \1代表第一个括号出现的位置即第一次出现的html
>>> re.match(r'<(.+)><(.+)>.+</\2></\1>',s)
<_sre.SRE_Match object; span=(0, 26), match='<html><h1>haha</h1></html>'>
>>> 

>>> s = '<html><h1>haha</html></h1>'
>>> re.match(r'<(.+)><(.+)>.+</\2></\1>',s)
>>> 
  • 提取邮箱@前内容
    ()代表()中的4个值取一个
>>> r = r'(\w+)@(163|126|gmail|qq)\.(com|cn|net)$'
>>> r = re.match(r,'321@qq.com')
>>> r.group(1)
'321'
  • (?P<name>) 分组起别名 (?P=name)引用别名为name分组匹配到的字符串
    分组多容易乱的情况下选择分组起别名
 >>> s = '<html><h1>haha</h1></html>'
>>> re.match(r'<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>',s)
<_sre.SRE_Match object; span=(0, 26), match='<html><h1>haha</h1></html>'>
>>> 

>>> s = '<html><h1>haha</h1></ht>'
>>> re.match(r'<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>',s)
>>> 
sub

将匹配到的数据进行替换

>>> s = 'java java python php cpp'
>>> re.sub(r'java','python',s)
'python python python php cpp'
>>> 

匹配出来的东西不同,替换的东西也不同
sub 接收的第二个参数可以是一个函数,在替换时他所执行的过程
>>> s = 'python=1000,java=0'
>>> def replace(result):
...     r = int(result.group()) + 50
...     return str(r)
... 
>>> re.sub(r'\d+',replace,s)
'python=1050,java=50'
>>> 
这个网址前面的容易进行匹配,而且匹配别的网站可复用性强,
此时可以将要返回的部分放到分组里,利用函数将分组中的内容
进行返回作为替换的部分。这里采用lambda表达式进行返回。
>>> s = "http://ww.baidu.com/fsdserwrewaf.adp?fdsa"
>>> re.sub('(http://.+?/).*',lambda x:x.group(1),s)
'http://ww.baidu.com/'
利用不同的思路达到相同的效果
>>> s = 'hello word ha ha'
>>> re.split(' ',s)
['hello', 'word', 'ha', 'ha']
>>> re.findall(r'\b[a-zA-Z]+\b',s)
['hello', 'word', 'ha', 'ha']
>>> 
split

根据匹配进行切割字符串,并返回一个列表

>>> s = 'itcast:php,python,cpp-java'
>>> re.split(':|,|-',s)
['itcast', 'php', 'python', 'cpp', 'java']tan
>>> 
python贪婪和非贪婪

python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试尽可能多的字符
非贪婪则相反,总是尝试匹配尽可能少的字符。

\d+表示的意思是有一个数字就满足,此时.+是贪婪模式会尽可能多的去匹配,所以23会匹配到前面

>>> s = 'this is number 234-235-22-423'
>>> r = re.match('(.+)(\d+-\d+-\d+-\d+)',s)
>>> r.groups()
('this is number 23', '4-235-22-423')

此时.+ 后面跟了?表示关闭贪婪模式,后面的\d+是贪婪模式,会尽可能多的进行匹配,所以23满足条件会匹配到后面,而匹配到空格不满足,'this is number '就是前面关闭贪婪模式的最小集合。

>>> r = re.match('(.+?)(\d+-\d+-\d+-\d+)',s)
>>> r.groups()
('this is number ', '234-235-22-423')
>>> 

>>> re.match(r'aa(\d+)',"aa2345bbb").group(1)
'2345'
>>> re.match(r'aa(\d+?)',"aa2345bbb").group(1)
'2'
>>> re.match(r'aa(\d+)bbb',"aa2345bbb").group(1)
'2345'
为什么这里关闭了贪婪模式还会匹配到2345呢因为要满足整个正则表达式去匹配,虽然\d+?只要有一个就满足,但是为了满足整体的正则表达式就必须把2345都给他才可以。
>>> re.match(r'aa(\d+?)bbb',"aa2345bbb").group(1)
'2345'

⚠️ 一般情况下正则部分建议加r,如用\b匹配单词边界,如果前面不加r, 那么解释器认为是转义字符“退格键backspace”;如果前面加r, 那么解释器不会进行转义,\b 解释为正则表达式模式中的字符串边界。

相关文章

网友评论

    本文标题:python re正则表达式

    本文链接:https://www.haomeiwen.com/subject/rqlbfhtx.html