python3基础:正则(一)

简介

正则是一个字符串规则,本身也是一个字符型,用来检查一个串是否含有字串。可以做精确匹配,模糊匹配,进行字符串替换,切割,尤其是在造数据,分析日志时用的非常多。

python中处理正则表达式的模块是re模块,正则表达式由一些普通字符和一些元字符组成,普通字符包括大小写字母、数字和打印符号,而元字符是具有特殊含义的字符。

正则表达式模式

正则表达式大致的匹配过程是:

拿正则表达式依次和字符串或者文本中的字符串做比较,如果每一个字符都匹配,则匹配成功,只要有一个匹配不成功的字符,则匹配不成功。模式字符串使用特殊的语法来表示一个正则表达式:

  1. 字母和数字匹配它们自身;
  2. 多数字母和数字前加一个反斜杠(\)时会有特殊含义;
  3. 特殊的标点符号,只有被转义以后才能匹配自身;
  4. 反斜杠本身要用反斜杠来转义

  注意:

  1. 由于正则表达式通常版本反斜杠等特殊字符,所以最好使用原始字符串来表示他们。如:r’\d’等价于’\\d’,表示匹配一个数字
  2. 正则表达式中数量词默认都是贪婪的,会尽可能多的去匹配满足的字符串,但是如果在后面加上问号’?’,就可以屏蔽贪婪模式,表示匹配尽可能少的字符。如:’xyyyyzs’,使用正则’xy*’,就会得到'xyyyy',如果使用’xy*?’,会得到'x'

 

 特殊表达式含义

符号

含义

举例

一般字符(匹配自身)

.(点)

匹配除换行符之外的任意一个字符DOTALL模式中可以匹配换行符

a.c可以匹配abc

\(反斜杠)

转义一个特殊的字符,使这个字符表示原来字面上的意思。如"\$",表示原字符$,而不是正则表达式中表示匹配行尾的意思。

a\.c匹配a.c

预定义字符集(可以写在[]中)

[...] 方括号

匹配括号中出现的任意单个字符

a[123]b匹配a1b、a2b、a3b、a12b等

[^...]

不匹配方括号中列出的单个字符(注意只能针对单个字符)

[^ab]匹配除a和b之外的字符

\d

匹配中任意一个数字,范围为[0-9]

a\dc可以匹配a1c、a2c等

\D

匹配任意一个非数字字符,等价于[^\d]

1\D2可匹配1a2

\s

匹配任意一个空白字符:[<空格>\t\r\n\v\f]

a\sf匹配a f

\S

匹配任意一个非空白字符,等价于[^\s]

a\Sg匹配agg等

\w

匹配一个字母或数字,字符范围:[A-Za-z0-9]

1\wt可以匹配1at等

\W

非单词字符,等价于[^\w]

a\Wb可以匹配a@b等

数量字符集(用在字符或分组符(...)之后,非贪婪匹配*? +?)

*(星号)

匹配前一个字符0次1次或多次

abc*可以匹配ab、abc、abcc等

+(加号)

匹配前一个字符1次或多次

cde+可匹配cde、cde等

?(问号)

匹配前一个字符0次或1次

fgh?匹配结果fg、fgh

{m}

匹配前一个字符m次

qc{3}匹配结果qccc

{m,n}

匹配前一个字符m到n次

{m,}匹配前一个字符至少m次

{,n}匹配前一个字符0到n次,最多n次

1{2,5}ac匹配结果11ac、111ac、1111ac、11111ac

 

符号

含义

举例

 

边界匹配符

^(托字符)

匹配字符串开头,如果是多行则匹配每一行的开头。在[...]中,^表示否定,如非字母[^a-zA-Z],非数字[^0-9]

^123匹配123

a[^0-9]b可匹配aab等

 

$(美元符)

匹配字符串或一行的结尾,如果是多行则匹配每一行的结尾

abc$匹配abc

 

\A

匹配字符串开始,如果存在换行,将字符当作一个整体

\A12AC匹配12AC

 

\b

匹配一个单词的边界,也就是指单词和空格间的位置

\bst匹配a test中的'st',但不匹配'tester'中的''st

\B

[^\b],表示匹配非单词边界

\Bst可以匹配'tester'而不能匹配'test'

\Z

匹配字符串结束,如果存在换行,将字符当作一个整体

abt\Z匹配abt

 

逻辑匹配符

|(或)

|或匹配符,表达左右正则表达式任意匹配一个。如果左边的表达式匹配上了,匹配结束,不再匹配右边的表达式。该符号一般放在()中使用,如果没在圆括号中则它的范围是整个正则表达式。

(12|34)匹配12或34

 

分组匹配

(...)

后向引用。用()括起来的正则表达式将被作为一个分组,从正则表达式的左边依次算起,有多少个左括号'(',就有多少个分组,分组的编码从1依次加1,无论是括号中嵌套括号。并且分组表达式作为一个整体,后可接数量词。

(xyz){2}满足xyzxyz

x(12|34)y匹配x12y或x34y

 

\<number>

引用分组匹配到的分组编号为<number>的字符串

如:\1...\9

 

(?P<name>...)

命名分组,除了默认的分组编号外再指定一个别名分组

注意:P是大写

(?P=name)

引用别名为name的分组匹配,这个是在正则表达式中引用,表示匹配重复的字符串,也可以使用编号引用。

注意:P是大写

特殊匹配符(不能作为分组使用)

(?:...)

(?!pattern)

前向否定断言语法,表示否定开头。只能用在正则表达式的开头,pattern是匹配模式,它后面的内容需要不匹配该正则表达式才匹配成功。

(?<!pattern)

后向否定断言语法,表示否定结尾,前面的内容需要不匹配该pattern模式才匹配成功。

(?=pattern)

前向肯定断言语法,需要匹配pattren模式才能匹配成功,表示肯定前面的字符内容。

(?<=pattern)

后向肯定断言语法,需要匹配pattern模式才能匹配成功,表示肯定后面的字符内容。

(?#...)

#后面的内容将被作为注释而忽略

.(点)

匹配除换行符之外的所有字符。可以在DOTALL模式中可以匹配换行符。

>>> import re

>>> re.match(r'.','and23__09')

<_sre.SRE_Match object; span=(0, 1), match='a'>#返回的是匹配结果的对象,span表示是是匹配的开始位置和结束位置,开区间



>>> re.match(r'..','and23__09')

<_sre.SRE_Match object; span=(0, 2), match='an'>

>>> re.match(r'..........','and23__09')#匹配的个数比字符中多的时候,返回的是None

>>> print(re.match(r'.','\n'))

None



>>> re.match(r'.','\n',re.DOTALL)#可以匹配换行符

<_sre.SRE_Match object; span=(0, 1), match='\n'>

 

多行字符串的两种实现方式:

三引号

>>> '''hello

... python

... 123'''

'hello\npython\n123'

单引号里面包含\n

>>> print('abc\ndef')

abc

def

 \(反斜杠)

>>> print(re.match(r"\.",".a\nc"))#匹配 .
<_sre.SRE_Match object; span=(0, 1), match='.'>
>>> print(re.match(r"\\","\\a\nc"))#匹配 \本身
<_sre.SRE_Match object; span=(0, 1), match='\\'>

 

 [...]方括号:

匹配括号中指定的某一个字符,但是只能匹配一个字符。​​​​​

>>> print(re.match(r"[abc]","axxx")) #匹配字符a
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> print(re.match(r"[abc]","bxxx")) #匹配字符b
<_sre.SRE_Match object; span=(0, 1), match='b'>
>>> print(re.match(r"[abc]","cxxx"))  #匹配字符c
<_sre.SRE_Match object; span=(0, 1), match='c'>

 

 

[^...]

不匹配括号中指定的任何一个字符,但是只能匹配一个字符(注意^在方括号里面表示非,在方括号外面表示开头匹配)

>>> print(re.match(r"[^abc]","hxxx"))  #匹配开头是非abc之外的任意一个字符
<_sre.SRE_Match object; span=(0, 1), match='h'>
>>> print(re.search(r"abc","sssssabc")) #匹配abc,可以不是开头
<_sre.SRE_Match object; span=(5, 8), match='abc'>

>>> print(re.search(r"^abc","sssssabc"))#匹配以abc开头的字符

None

>>> print(re.match(r"\d","123"))#匹配一次

<_sre.SRE_Match object; span=(0, 1), match='1'>

>>> print(re.match(r"\d+","123"))#匹配一次或多次

<_sre.SRE_Match object; span=(0, 3), match='123'>

>>> print(re.match(r"\d*","123"))#匹配0次或多次

<_sre.SRE_Match object; span=(0, 3), match='123'>

 

 

 \d

匹配中任意一个数字,范围为[0-9]

>>> re.match(r"\d","123").group()
'1''

 

 

 \D

匹配任意一个非数字字符,等价于[^\d]

>>> re.match(r"\D+","a123").group()
'a'
>>> re.match(r"\D+","abc123").group()
'abc'

 

 \s

匹配任意一个空白字符:[<空格>\t\r\n\v\f]

>>> re.search(r'\s','anb \t \r \n')

<_sre.SRE_Match object; span=(3, 4), match=' '>

>>> re.search(r'\s+','anb \t \r \n')

<_sre.SRE_Match object; span=(3, 9), match=' \t \r \n'>

 

 

 \S

匹配任意一个非空白字符,等价于[^\s]

>>> re.findall(r"\S+","ab cd\t ef\nhi")
['ab', 'cd', 'ef', 'hi']

>>> "".join(re.findall(r"\S+","ab cd\t ef\nhi")) #去掉了字符串中所有的空白字符
'abcdefhi'

 

 

 \w

匹配一个字母,数字和下划线,字符范围:[A-Za-z0-9_]

>>> re.search(r'\w','12bsc_-')

<_sre.SRE_Match object; span=(0, 1), match='1'>

>>>

>>> re.search(r'\w+','12bsc_-')

<_sre.SRE_Match object; span=(0, 6), match='12bsc_'>

>>>

 \W

非字母,数字和下划线,等价于[^\w]

>>> re.search(r'\W+','12bsc_-')

<_sre.SRE_Match object; span=(6, 7), match='-'>

>>> re.search(r'\W+','a@b')

<_sre.SRE_Match object; span=(1, 2), match='@'>

 

 *

匹配一个字符0次或多次,注意正则默认的贪婪性,贪婪性指的是在满足匹配的条件下再继续贪婪更多的匹配

>>> print(re.match(r"\d*","123"))

<_sre.SRE_Match object; span=(0, 3), match='123'>

>>> print(re.match(r"\d*?","123"))  #用问号抑制贪婪,*最小是0次匹配
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> print(re.match(r"\d+?","123"))#用问号抑制贪婪,+最小是1次匹配
<_sre.SRE_Match object; span=(0, 1), match='1'>

>>> print(re.search(r'\d*','abc123'))

<_sre.SRE_Match object; span=(0, 0), match=''>

 search有匹配就会返回,字符串不是数字开头,匹配0次,所以返回的是空

 

 

 ?

匹配一个字符0次或1次,?用在数量词(*/+/{m}/{m,n})后面才表示抑制贪婪性

>>> re.search(r"\d?","a7").group() #不是以数字开头,匹配了0次,所以返回空字符

''

>>> re.search(r"\d?","7").group() #以数字开头,匹配了1次,所以返回7

'7'

 

 

 +

匹配一个字符1次或多次,注意正则默认的贪婪性。

>>> s = "abc123dee"

>>> re.search(r'\d+',s)

<_sre.SRE_Match object; span=(3, 6), match='123'>

>>> re.search(r'\d+',s).group()

'123'

>>> re.search(r"\d+","7").group()

'7'

>>> print(re.match(r"\d+?","123"))#用问号抑制贪婪,+最小是1次匹配
<_sre.SRE_Match object; span=(0, 1), match='1'>

 

 {}

匹配次数

{m}:匹配前一个字符m次

{m,n}:匹配前一个字符m到n次

{m,}匹配前一个字符至少m次

{,n}匹配前一个字符0到n次,最多n次

>>> re.search(r'\d{2}',"abc123dee").group()

'12'

>>> re.search(r"\d{3}","123456789").group()
'123'
>>> re.search(r"\d{1,3}","123456789").group() #贪婪性
'123'
>>> re.search(r"\d{1,3}?","123456789").group()
'1'

 

 ^(脱字符)

匹配字符串开头,如果是多行则匹配每一行的开头。在[...]中,^表示否定,如非字母[^a-zA-Z],非数字[^0-9]

>>> re.search(r"^abc","dddabc")

>>> re.search(r"^abc","abcabc")

<_sre.SRE_Match object; span=(0, 3), match='abc'>

>>> re.search(r"^abc","abcde\nabc")

<_sre.SRE_Match object; span=(0, 3), match='abc'>

 

 

 $(美元符)

匹配字符串或一行的结尾,如果是多行则匹配每一行的结尾

>>> re.search(r"^\d+","133dddabc")
<_sre.SRE_Match object; span=(0, 3), match='133'>
>>> re.search(r"\d+$","133dddabc5555")
<_sre.SRE_Match object; span=(9, 13), match='5555'>

>>> re.search(r"^123$","123")

<_sre.SRE_Match object; span=(0, 3), match='123'>

 

 

 \A

非多行匹配的时候等价于^,多行匹配的是\A将整个字符串看做一个整体匹配,而^能够则匹配每一行的结尾

>>> re.search(r"\Aabc","abcabc")

<_sre.SRE_Match object; span=(0, 3), match='abc'>

>>> s = '124\n453\n'

>>> re.search(r'^\d',s)

<_sre.SRE_Match object; span=(0, 1), match='1'>

>>> re.findall(r'^\d',s)

['1']

>>> re.findall(r'^\d',s,re.M)  #匹配多行文件每行的结尾

['1', '4']

>>> re.findall(r'\A\d',s,re.M)  #即使加了re.M,使用\A时仍然是将字符串看做一个整体

['1']

>>> re.findall(r'\A\d',s)#使用\A时仍然是将字符串看做一个整体

['1']

 \Z

非多行时等价于$,多行匹配\Z将整个字符串看做一个整体匹配,而$能够则匹配每一行的结尾。

>>> re.search(r"\A123\Z","123")

<_sre.SRE_Match object; span=(0, 3), match='123'>



>>> s = '124\n453\n'

>>> re.search(r'\d$',s)

<_sre.SRE_Match object; span=(6, 7), match='3'>

>>> re.search(r'\d\Z',s)  #没有匹配成功

>>> re.findall(r'\d$',s)

['3']

>>> re.findall(r'\d$',s,re.M) #匹配每一行的结尾

['4', '3']

>>> re.findall(r'\d\Z',s)

[]

>>> re.findall(r'\d\Z',s,re.M)#换行前的结束字符也不能匹配

[]



>>> s = '124\n453'

>>> re.findall(r'\d\Z',s,re.M)

['3']

>>> re.findall(r'\d\Z',s)

['3']

 

 

()分组

用()括起来的正则表达式将被作为一个分组,从正则表达式的左边依次算起,有多少个左括号'(',就有多少个分组,分组的编码从1依次加1,无论是括号中嵌套括号。并且分组表达式作为一个整体,后可接数量词。

>>> re.search(r"\d(\D+)\d","1abc3").group(1)

'abc'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group(1)

'1'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group(2)

'abc'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group(2)

'abc'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group(3)

'3'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group()#表示正则表达式匹配的全部内容,等价于group(0)

'1abc3'

>>> re.search(r"(\d)(\D+)(\d)","1abc3").group(0)

'1abc3'

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值