正则表达式

正则表达式又称规则表达式(Regular Expression),通过一定的规则,用来对文本(字符串)内容进行检索、替换。

要搜索的模式和字符串都可以是Unicode字符串(str)以及8位ASCII字符串(字节)。但是,Unicode字符串和ASCII符串不能混合使用。也就是说,无法将Unicode字符串与字节模式匹配,反之亦然;同样,当要求替换时,替换字符串必须与模式和搜索字符串的类型相同。

这些建立的规则在使用时又叫模式字符串。一个正则表达式模式中的字母和数字匹配同样的字符串。

  1. 字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。多数字母和数字前加一个反斜杠时会有不同的含义。
  2. 标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
  3. 反斜杠本身需要反斜杠转义。    由于正则表达式通常都包含反斜杠,所以最好使用原始字符串来表示它们。模式元素(如r'\t',等价于r'\\t')匹配相应的特殊字符。
  4. 正则表达式可以连接起来形成新的正则表达式。如果A和B都是正则表达式,那么AB也是一个正则表达式。通常如果一个字符串p匹配A而另外一个字符串q匹配B,那么,字符串pq匹配字符AB。除非A或B包含包含低优先级操作,A和B之间的边界条件,或者有编号的组参考。因此,复杂的表达式可以很容易地从简单的基本表达式构建,就像这里描述的那样。
  5. 正则表达式可以包含特殊字符和普通字符。大多数普通字符,如'A'、'a'或'0'是最简单的正则表达式。它们指数匹配自己。可以连接普通字符,因此最后匹配字符串'last'。

特殊字符,一些字符'|'或者'()'是特殊的,特殊字符或者代表普通字符类,或者影响它们周围正则表达式的解释方式。特殊符号和字符如下所示(主要包括普通字符、11个元字符、特殊字符):

符号使用说明示例
^匹配字符串的起始部分^Cat
$匹配字符串的末尾部分Cat$
.匹配任意字符,除了换行符(/n)Cat.cool
[···]用来匹配字符集中的任意单个字符[abc]
[^···]匹配不在[]中的字符[^abc]
*匹配0个或者多个的表达式[abc]*
+匹配1个或者多个的表达式[abc]+
?匹配0个或者1个由前面的正则表达式定义的片段Cat?
{n}精确匹配n次前面出现的表达式[0-9] {2}
{n,}匹配n次前面出现的表达式oo {2,}
{n,m}匹配n到m次由前面的正则表达式定义的片段,贪婪方式[0-9] {2,4}
a | b匹配a或者bCat | abc
(···)匹配括号内的表达式,然后另存匹配的值(abc ?)
(?-imx)正则表达式 关闭i、m或x可选标志,只影响括号中的匹配(?-imx)
(?···)类似(...),但是不另存匹配的值[?:abc]
(?imx:···)在括号中使用i、m或x可选标志(?imx:abc)
(?-imx:···)在括号中不使用i、m或x可选标志(?-imx:abc)
(?#.···)注释,所有内容都被忽略(?#OK)
(?=···)前向肯定界定符(?=.com)
(?!···)前向否定界定符(?!.cn)
(?>···)匹配的独立模式,省去回溯(?>20)
\w匹配任意字母、数字及下划线(\w)
\W匹配非字母、数字及下划线(\W)
\s匹配任意空白字符,等价于[\t\n\r\f](\s)
\S匹配任意非空字符(\S)
\d匹配任意数字(\d)
\D匹配任意非数字(\D)
\A匹配字符串开始\Agood
\Z匹配字符串结束,如果存在换行,只匹配到换行前的结束字符串good\Z
\z匹配字符串结束good\z
\G匹配最后匹配完成的位置Good\G
\b匹配一个单词边界,也就是指单词和空格间的位置Good \b and \b
\B匹配非单词边界T\B
\n,\t匹配一个换行符,匹配一个制表符Bird\n\t
\1...\9匹配第n个分组的内容\1abc

代码示例:

import re
m=re.search('(?<=abc)def','abcdef')
print(m.group(0))

m=re.search('(?<=-)\w+','spam-egg') #匹配从-开始的任意数字、字母及下划线
print(m.group(0))

输出结果:

def

egg

###########################################################################################

注意:Python的字符串本身也用'\'转义,所以要特别注意,一般我们都建议使用Python的r前缀,就不用考虑转义的问题了

 1,行的起始

例子:匹配‘cat’ 开头

patt=re.compile(r'^cat') # re.compile 返回一个正则表达式对象

表示匹配以c作为一行的第一个字符,后面跟着a,后面跟着t

所以'vocative'就不会被匹配到,原因是因为cat在字符的里面

 2,行的结尾

import re sentence='''Hi Jack:\n Python is a beautiful language\n BR''' 

patt=re.compile(r'(BR|Bestregards)$') 

m=re.search(patt,sentence) 

if len(m)>=0 : 
    print 'match' 
else: 
    print 'not match' 

>> match

     要查找sentence中是否以“BR或Bestregards” 结尾   

  3 ,单词的边界

正则里面有2个特殊字符\b and \B来匹配单词的边界 :

  • \b 匹配的模式是一个单词的边界(不论这个单词的前面是有字符还是没有字符)

  • \B 匹配出现在一个单词中间的模式

  • 例如:

the            #匹配包含有'the'的字符串

\bthe         #匹配任何以'the'开始的字符串

\bthe\b      #仅仅匹配单词'the'

\Bthe         #匹配任意包含'the'但不以'the'开头的单词

   4,字符组

   比如我们需要匹配'grey'或者'gray'的时候,怎么办,可以用正则的[]来表示,gr[ea]y,表示先找到g,然后找到r,然后找到e或者a,最后是一个y

patt=re.compile(r'gr[ea]y')#意思就是grey 或者gray都是可以匹配上的

   5,多选结构

我们可以用'|'来匹配任意子表达式,'|'是一个非常简便的元字符,它的意思是"或",通过它我们能把不同的子表达式组合成一个总的表达式,比如'am'|'pm'就是能够同时匹配其中任意一个的正则表达式,回头再看上面的例子'gr[ea]y',其实能写成'grey|gray',或者'gr(e|a)y'

6、可选项元素
'?' 表示可选项,问号跟在什么后面就表示什么是可选的
例如:6月4日,可能写成'June'也可以写成'Jun',而且日期也有可能写作'fourth'或者'4th'或者4,这个时候就可以写成June?(fourth|4(th)?),代表了e是可选的,th是可选的,可有可无都表示4号

7,重复出现
+,表示紧邻元素重复出现一次或者多次,至少出现一次,否则返回失败;
*,表示紧邻元素重复出现0次或者多次,允许出现0次;
例如:
  • a*表示0个或者多个a,所以为0的时候,就是空字符
  • a+表示1个或者多个a,所以a至少要有1次
8,匹配重复的次数
次数用{}里面的数字来表示
例如:patt=re.compile(r'([1-9]{3})') 就表示匹配1-9之间的数字,且这个数字只能出现3次,str='123str' ,就可以匹配上,而str1='2str1'就不能匹配,如果想匹配上要这么写patt1=re.compile(r'([1-9]{1-3})'),1-9数字出现1次或2次或3次

9、排除型字符组
  • 当^在字符组的外面的时候"表示一个行的开头"

  • 当^在字符组的内部(而且是必须紧接着字符组的第一个方括号之后),它就是一个元字符,表示排除型

  • 例如:找出字母g后面的字母不是u
  •  

    import re
    words=['gold',' Google','Sogu','Guess']
    patt=re.compile(r'.*g[^u]')   #‘.’匹配任意一个字符,'*'匹配0个或多个字符,g后面不是u 
    
    for w in words:
       m=re.match(patt,w)
       if m:
          print w
    
    >>
    gold
    Google

     

实战小例子
1,设计一个正则来过滤一个字符串序列中的10到59

 

import re

patt=r'[1-5][0-9]'

lis=[10,20,30,40,2,3,59,60,'aa','3aaa']

match=re.findall(patt,str(lis))

if match:
  print(match)

结果:
['10', '20', '30', '40', '59']

 

 2,过滤字符串中的只含2个字符的字母,并且第一个字母是大写A或B或C

patt=r'[A-C][A-Z a-z]'

3,过滤一个字符串中的含3个字母的独立字符

例如:比如这样的一个字符串'xy,1,2,?,123@sohu,Ab,w1,Cz,xyh,abc',只想过滤出来xyh,abc 这样的

patt=r'/b[a-z A-Z]{3}/b' #/b 单词的边界

4、过滤一个字符串中的含3个字母的字符,并且最后一个字母是z

patt=r'/b[a-z A-Z][a-z A-Z][Z]/b'

5,过滤正确的24小时时间制

 

import re
time='10:00,99:90,8:00,19:19:14:00pm,5:xm,6,00,8:0923:23pm,29:19pm,23:59'
patt = r'\b([01]?[0-9]|2[0-4])(:)([0-5][0-9])'
match = re.findall(patt,time)
if match:
    print([''.join(x)for x in match])

执行结果:
['10:00', '8:00', '19:19', '14:00', '8:09', '23:59']

****************************************************************************************************************

re模块中常用功能函数

1、compile()

编译正则表达式模式,返回一个对象的模式。(可以把哪些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率)

格式:

re.compile(pattern,flags=0)

标志flags:

  • re.S(DOTALL)  使.匹配包括行在内的所有字符
  • re.I(IGNORECASE)  使匹配对大小写不敏感
  • re.L(LOCALE)  使用本地化识别 (locale-aware)匹配,法语等
  • re.M(MULTILINE) 多行匹配,影响^和$
  • re.X(VERBOSE)  该标志通过给与更灵活的格式以便将正则表达式写得更易于理解
  • re.U  根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B
import re

tt ='Tina is a good girl,she is cool,clever, and so on...'

patt=re.compile(r'\w*oo\w*')
print(re.findall(patt,tt))

输出结果:

['good', 'cool']

2、match()

决定RE是否在字符串刚开始的位置匹配。

print(re.match('com','comwwwww.runconoob').group())
print(re.match('com','CoMEEEE',re.I).group())

输出结果:

com
CoM

3、search()

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

re.search()函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。

re.search('\dcom','ddd2dcom.333ss.1com').group())

输出结果:
2com

注意:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:

  • group()返回被RE匹配的字符串
  • start()返回匹配开始的位置
  • end()返回匹配结束的位置
  • span()返回一个元组包含的匹配(开始,结束)的位置
  • group()返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串
a = "123abc456"
 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0))   #123abc456,返回整体
 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1))   #123
 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2))   #abc
 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3))   #456
###group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。###

4、findall()

re.findall()遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。

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

示例:

p=re.compile(r'\d+')
print(re.findall(p,'o1m2n3b4'))

输出结果:
['1', '2', '3', '4']



tt ='Tina is a good girl,she is cool,clever, and so on...'
print(re.findall('(\w*)oo(\w)',tt))

输出结果:
[('g', 'd'), ('c', 'l')]

5、finditer()

搜索string,返回一个顺序访问每一个匹配结果的迭代器。找到RE匹配的所有子串,并把它们作为一个迭代器返回。

6、split()

按照能够匹配的子串将string分割后返回列表

可以使用re.split来分割,如:re.split(r'\s+',text),将字符串按照空格分割成一个单词列表。

print(re.split(r'\d+','ddd1eeeee23ddddd45mmmm6'))


输出结果:
['ddd', 'eeeee', 'ddddd', 'mmmm', '']

7、sub()

使用re替换string中每一个匹配的子串后返回替换后的字符串

格式:re.sub(pattern,repl,string,count)

tt ='Tina is a good girl,she is cool,clever, and so on...'
print(re.sub('\s+','-',tt))    #将空格替换为-

输出结果:
Tina-is-a-good-girl,she-is-cool,clever,-and-so-on...

8、subn()

返回替换的次数。

格式:re.subn(pattern,repl,string,count=0,flags=0)

tt ='Tina is a good girl,she is cool,clever, and so on...'
print(re.subn('\s+','-',tt))    #subn()得到替换的次数

输出结果:
('Tina-is-a-good-girl,she-is-cool,clever,-and-so-on...', 9)

注意点

1、re.match与re.search、re.findall()的区别

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

a=re.search('[\d]',"abc33").group()
print(a)
p=re.match('[\d]',"abc33")
print(p)
b=re.findall('[\d]',"abc33")
print(b)

执行结果:
3
None
['3', '3']

2、贪婪匹配与非贪婪匹配

*?  +?  ?? {m,n}?前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?使其编程惰性匹配。(如果前后都有限定条件,则不存在贪婪模式)

a=re.findall(r'a(\d+?)','a23456dddd')
print(a)
b=re.findall(r'a(\d+)','a23456drr456dddd')
print(b)


输出结果:
['2']
['23456']

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值