无论你做开发,还是测试,或者运维,正则表达式是一个IT行业从业者绕不过去的东西。

之前我面试过Nvida,面试官问了很多正则表达式的内容,这个地方非常的因吹斯汀,需要你花一定的时间进行学习巩固。

 

了解python之正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。

re模块中,常用的3个函数是:

re.compile,re.match,re.search

正则匹配的时候,第一个字符是r,表示的是原生字符,意在声明字符串中间的特殊字符不用转义。比如表示‘\n’,可以写成r'\n'.  re.match、re.search都是精确匹配.

 

re.compile()函数
编译正则表达式的模式,返回一个对象。可以把常用的正则表达式编译成正则表达式对象,方便后续调用及提高效率。

re.compile(pattern,flags=0)

  • pattern--指定编译时的表达式字符串
  • flags--编译标志位,用来修正正则表达式的匹配方式,支持re.L|re.M同时匹配

 

例1:

import re
content = 'Mr wang, always fall in love with neighbour,such as Mrs WANG'
rr=re.compile(r'wan\w',re.I)
print(rr)
print(type(rr))
a=rr.findall(content) #findall 返回的是一个 list 对象
print(a)

##输出结果
re.compile('wan\\w', re.IGNORECASE)
<class 're.Pattern'>
['wang', 'WANG']


##
模式元素(r'\t',等价于\\t)匹配相应的特殊字符, 所以 r'wan\w' ----> 'wan\\w', 而\w 表示匹配字母数字下划线;
re.I 表示匹配对大小写不敏感;

 

flags标志位有哪些参数:

  • re.I     匹配对大小写不敏感
  • re.L    本地化识别匹配
  • re.M  多行匹配,影响^和$
  • re.S  匹配包括换行在内的所有字符
  • re.U  根据Unicode字符集解析字符,这个影响\w,\W,\b,\B
  • re.X  给予你更灵活的格式,以便你将正则表达式写的更易于理解

 

pattern正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式:字母和数字表示它们本身。一个正则表达式模式中的字母和数字匹配同样的字符串。

字母和数字前面加一个\会拥有不同的含义。标点符号只有被转义时才能匹配自身,否则它们表示特殊的含义。反斜杠\本身需要反斜杠转义。由于正则表达式通常都包含反斜杠,所以最好使用原始字符串表示它们。模式元素(r'\t',等价于\\t)匹配相应的特殊字符.

 

下面列出正则表达式语法中的特殊元素,如果使用模式的同时还提供了可选的标志参数,某些模式元素的含义会改变。

  • ^ 匹配字符串的开头
  • $ 匹配字符串的末尾
  • . 匹配除了换行符之外的任意字符,当re.DOTALL标志位被指定的时候,则可以匹配包括换行符在内的任意字符
  • [..] 用来表示一组字符,[abc]表示匹配'a'、'b'、'c'
  • [^...] 匹配不在[]中的字符,[abc]表示匹配除了a和b和c之外的字符
  • re* 匹配0个或者多个表达式
  • re+ 匹配1个或者多个表达式
  • re? 匹配0个或者1个由前面的正则表达式定义的片段
  • re{n} 匹配n个前面的表达式,例如o{2}不能匹配‘Bob’中的o,但是能匹配‘food’中的o
  • re{n.} 精确匹配n个前面的表达式,例如o{2.}不能匹配Bob中的o,但是能匹配fooood中的所有o
  • re{n..m} 匹配n到m次由前面的正则表达式定义的片段
  • a|b    匹配a或者b
  • {re} 匹配括号内的表达式,也表示一个组
  • \w  匹配字母数字下划线
  • \W  匹配非字母数字下划线
  • \s   匹配任意空白字符,等价于\t,\n
  • \S   匹配任意的非空字符
  • \d   匹配任意数字,等价于[0-9]
  • \D   匹配任意的非数字
  • \A   匹配字符串开始
  • \Z   匹配字符串结束,如果是存在换行的话,只匹配到换行前的结束字符串
  • \z   匹配字符串结束
  • \G   匹配最后匹配完成的位置
  • \b   匹配一个单词边界,也就是指单词和空格间的位置,例如:‘er\b’可以匹配‘never’中的er,但是不能匹配‘verb’中的er
  • \B   匹配非单词边界。‘er\B’能匹配‘verb’中的er,但是不能匹配‘never’中的er
  • \n  匹配一个换行符
  • \t  匹配一个水平制表符
  • \1...\9 匹配第n个分组的内容
  • \10  匹配第n个分组的内容

 

 

re.match()
从字符串开始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None

语法:

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

  • pattern-匹配的正则表达式
  • string-匹配的字符串
  • flags--标志位

匹配成功的话re.match()方法返回一个对象,否则返回None。可以使用group()或者groups()匹配对象函数来获取匹配的表达式。

  • group(num=0)   匹配的整个表达式的字符串,group()可以一次输入多个逗号,在这种情况下它将返回一个包含那些组所对应值的元组
  • groups()      返回一个包含所有小组字符串的元组,从1到所包含的小组号

例2:

import re
str='hello 123456789 hello_word is good a lucky'
result=re.match('^hello\s\d{9}.*lucky$',str)
print(result)
print(result.group())

##输出结果:
<re.Match object; span=(0, 42), match='hello 123456789 hello_word is good a lucky'>
hello 123456789 hello_word is good a lucky


result=re.match('^hello\s\d{9}.*lucky$',str)分析如下:
# ^表示以hello开头的字符串
# \s 匹配的是空白字符
# \d{9}匹配9位数字
# .匹配除了换行符之外的任意字符,*匹配0次或者多次,两者结合起来可以匹配任意字符(不包括换行符)
# $表示以lucky结尾的字符串

 

re.search()
扫描整个字符串并且返回第一个成功的匹配

语法:

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

  • pattern-匹配的正则表达式
  • string-匹配的字符串
  • flags--标志位

匹配成功的话re.match()方法返回一个对象,否则返回None。
我么可以使用group()或者groups()匹配对象函数来获取匹配的表达式。

group(num=0)   匹配的整个表达式的字符串,group()可以一次输入多个逗号,在这种情况下它将返回一个包含那些组所对应值的元组
groups()      返回一个包含所有小组字符串的元组,从1到所包含的小组号

 

例3:

import re
print(re.search('www','www.lucky.www.com').group())
print(re.search('com','www.lucky.www.com').group())

##输出结果
www
com

 

例4:

import re
line="Cats are smarter than dogs"
searchObj=re.search(r'(.*) are (.*?) .*',line,re.M|re.I)
if searchObj:
    print('searchObj.group():',searchObj.group())
    print('searchObj.group(1):', searchObj.group(1))
    print('searchObj.group(2):', searchObj.group(2))
else:
    print('Nothing found...')

##输出结果
searchObj.group(): Cats are smarter than dogs
searchObj.group(1): Cats
searchObj.group(2): smarter

 

例5:

import re
str='hello,my name is lucky'
p=re.compile('hello')
c=p.match(str)        #match表示匹配到以hello开头的行
print(c.group())      #匹配到则显示hello

##输出结果
hello



import re
str='H hello,my name is lucky'
p=re.compile('hello')
c=p.match(str)
print(c.group())

##输出结果
    print(c.group())
AttributeError: 'NoneType' object has no attribute 'group'

 

例6:

import re
p=re.compile('my')
str='hello,my name is lucky'
print(p.search(str))
c=p.search(str)
print(c.group())


#输出结果
<re.Match object; span=(6, 8), match='my'>
my

 

注意点:

  • match()和search()都是精确匹配,macth()匹配的是开头的字符串,search()匹配的是任意位置的字符串
  • 模糊匹配findall(),把匹配的内容以列表的形式存起来

 

常见的正则匹配样例:

1)'\S','\s'
import re
str='hello,my name is lucky'
print(re.findall('\S+',str))   #\S+表示匹配一个或者多个非空白字符,以列表的形式存起来
print(re.findall('\s+',str))   #\s+匹配一个或者多个空白字符

#输出结果
['hello,my', 'name', 'is', 'lucky']
[' ', ' ', ' ']



2)'\D','\d'
import re
a='one1two2three3four4five5'
print(re.findall('\d+',a))  #匹配数字
print(re.findall('\D+',a))   #匹配非数字

#输出结果
['1', '2', '3', '4', '5']
['one', 'two', 'three', 'four', 'five']



3)\\转义,表示可以匹配到\
import re
a='abc\\dfe\\gkl\\'
print(re.findall('\\\\',a))

输出结果:
['\\', '\\', '\\']



4). 匹配任意单个字符
import re
a='one1two2three3four4five5'
print(re.findall('.',a))

##输出结果
['o', 'n', 'e', '1', 't', 'w', 'o', '2', 't', 'h', 'r', 'e', 'e', '3', 'f', 'o', 'u', 'r', '4', 'f', 'i', 'v', 'e', '5']


5).+ 匹配所有的内容
import re
a='one1two2three3four4five5'
print(re.findall('.+',a))

##输出结果:
['one1two2three3four4five5']


6)\w 匹配字母数字下划线
import re
a='one1two2three3four4five5'
print(re.findall('\w',a))

##输出结果
['o', 'n', 'e', '1', 't', 'w', 'o', '2', 't', 'h', 'r', 'e', 'e', '3', 'f', 'o', 'u', 'r', '4', 'f', 'i', 'v', 'e', '5']


7)\W 匹配除了字母数字下划线的内容
import re
a='one1two2three3four4five5 aaa | www'
print(re.findall('\W',a))

##输出结果:
[' ', ' ', '|', ' ']


8)
[0-9]匹配任意一个数字
[a-z]匹配任意一个字母

import re
a='one1two2three3four4five5 aaa | www'
print(re.findall('[0-9]',a))
print(re.findall('[a-z]',a))

#输出结果:
['1', '2', '3', '4', '5']
['o', 'n', 'e', 't', 'w', 'o', 't', 'h', 'r', 'e', 'e', 'f', 'o', 'u', 'r', 'f', 'i', 'v', 'e', 'a', 'a', 'a', 'w', 'w', 'w']


9)
^ 匹配开头
$ 匹配结尾

import re
a='one1two2three3four4five5 aaa | www'
print(re.findall('^o',a))
print(re.findall('w$',a))

##输出结果
['o']
['w']