python 正则表达式笔记

https://www.cnblogs.com/Ting-light/p/9548306.html

#!usr/bin/env python3

#-*- coding:utf-8 -*-

import re 

# re.match('re_expression','strings')  match中的正则表达式会从给定字符串的第一个字符开始匹配,如果前面N个字符不符合,则返回None,否则返回匹配的字符串,match()只返回满足字符串中第一个满足表达式的子串

re_m = re.match(r'\d{3}-d','010-12345')

re_text = re_m.group(0)

#'010-1

re_m2 = re.match(r'\s\d{3}-d','010-12345')

#re_m2的值为None

match后的结果用group()来获取, group()等于group(0)返回满足整个正则表达式的字符串, group(1),返回表达式中的第一个分组的内容,group(2)返回第二个分组的内容,groups()返回分组1,分组2,。。组成的一个元组

mol = re.compile(r'(\d{3}\w([.A-F]{2,4})[F-Z]{2})')

#mol.search('strings') 与 match相比,search可以从内容的中间开始匹配,其他的同match,只返回第一个满足的子串

mol.search('asd123A.EVU23').group()

#'123A.EVU'

#findall 与search,match相比,查找时可以从内容的任意位置开始,也可以返回所有的 符合的子串

mo1=re.compile(r'''(\d{3}\w{2}([.A-F]{2,4})[%@F-Z]{3})''',re.VERBOSE)

A = mo1.findall('576dfCD.HIS794SDABC@KM')

#[('576dfCD.HIS','CD.'),('794SDABC@KM','ABC')]

compile()的第二个参数,可以设定正则表达式的一些特性

re.VERBOSE                                  用于忽视正则表达式中的 空白符和注释

re.I或re.IGNORECASE                 让正则表达式忽视大小写

re.DOTALL                                    让正则中的句点符匹配所有的字符,包括换行符

如果需要同时使用多个特性,可以用|连接多个特性值

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL)

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL|re.VERBOSE)

使用正则表达式分割字符串

re.split(r'\s+','a b  c')

#['a','b','c']

使用正则表达式匹配需替换的字符串

namesRegex=re.compile(r'Agent \w+')

namesRegex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')

#'CENSORED gave the secret documents to CENSORED.'

#正则表达式

#在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母、数字或下划线 . 英文点号可以匹配任意单个字符,换行符除外。

#\s 可以匹配一个空格(也包括Tab等空白符),对于特殊字符- ,在正则表达式中要用转义字符\转义。

#\D 匹配除0到9的数字以外的任何字符 ,\W 匹配除数字、字母和下划线以外的任何字符,\S 匹配除空格、制表符和换行符以外的任何字符

#变长字符:表示匹配前一个字符的次数   *表示0个或多个字符  + 表示至少一个字符,?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

#\d{3}\s+\d{3,8} 表示匹配3个数字和一个或多个空格和3-8个数字

#中括号[]可以自定义匹配范围,表示可以是里面的任意一个

#[a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个数字、字母或下划线组成的字符串,也就是Python合法的变量。

#A|B可以匹配A或B,所以 (P|p)ython 可以匹配Python 或 python .

#^表示行的开头,^\d 表示必须以数字开头。 $表示行的结束,\d$表示必须以数字结束。

#py也可以匹配python,但是加上^py$就变成了整行匹配,就只能匹配py了。

#在字符串前加上r,表示对立面的字符不转义。

import re 

re.match(r'^\d{3}\-\d{3,8}$','010-12345') 

re.match(r'^\d{3}\-\d{3,8}$','010 12345')

#match()方法判断是否匹配,如果匹配成功,返回一个match对象,否则返回None.

#经Python3.5测试,只有res2有匹配到值,res1,res3都返回None。match是根据匹配模式从给定字符串的第一个字符开始匹配,如果第一个字符就不符合,则返回None

'''

>>> pattern=re.compile(r'hello')

>>> res1=re.match(pattern,'hell')

>>> res2=re.match(pattern,'hellow')

>>> res3=re.match(pattern,'ashello')

>>> res1

>>> res2

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

>>> res3

'''

# 分组

# 除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group).比如 ^(\d{3})-(\d{3,8})$分别定义了两个组,

#可以直接从匹配的字符串中提取出区号和本地号码:

m=re.match(r'^(\d{3})-(\d{3,8})$','010-12345')

print(m.group(0),

m.group(1),

m.group(2))

#010-12345 010 12345

#group(0)永远是原始字符串,group(1)、group(2)……表示第1/2、……个子串。

#贪婪匹配

#正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。例,匹配出数字后面的0:

re.match(r'^(\d+)(0*)$','102300').groups()

#('102300', '')

#由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。

re.match(r'^(\d+?)(0*)$','1022300300').groups()

#('10223003', '00')

'''

import re 

mo1=re.compile(r'''(\d{3}\w{2}([.A-F]{2,4})[%@F-Z]{3})''',re.VERBOSE)

A = mo1.findall('576dfCD.HIS794SDABC@KM')

for n in A:

    print(n[0])

'''

#用管道“|”匹配多个分组。

#希望匹配许多表达式中的一个时,可以用它

#如r'Batman|Tina Fey'将匹配‘Batman或Tian Fey .如果Batman和Tina Fey 都出现在被查找的字符串中,第一次出现的匹配文本将作为Match对象返回。

heroRegex=re.compile(r'Batman|Tina Fey')

mo1=heroRegex.search('Batman and Tina Fey.')

print(mo1.group())

#Batman

#也可以使用管道来匹配多个模式中的一个,作为正则表达式的一部分。

#比如你希望匹配Batman,Batmobile,Batcopter和Batbat中任意一个。

batRegex=re.compile(r'Bat(man|mobile|copter|bat)')

mo=batRegex.search('Batmobile lost a wheel')

#点-星将匹配除除换行符外的所有字符。

#通过传入re.DOTALL作为re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行符。

noNewlineRegex=re.compile('.*')

m='Serve the public trust.\nProtect the innocent.\nUphold the law.'

n=noNewlineRegex.search(m).group()

print(n)

#'Serve the public trust.'

newlineRegex=re.compile('.*',re.DOTALL)

print(newlineRegex.search(m).group())

'''

Serve the public trust.

Protect the innocent.

Uphold the law.

'''

#不区分大小写的匹配,可以向re.compile()传入re.IGNORECASE或re.I,作为第二个参数。

robocop=re.compile(r'robocop',re.I)

robocop.search('Robocop is part man,part machine,all cop.').group()

#'Robocop'

#用sub()方法替换字符串

#正则表达式不仅能找到文本模式,而且能够用新的文本替换掉这些模式。

#Regex对象的sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式。sub()方法

#返回替换完成后的字符串。

namesRegex=re.compile(r'Agent \w+')

namesRegex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')

#'CENSORED gave the secret documents to CENSORED.'

#有时候,你可能需要使用匹配的文本本身,作为替换的一部分,在sub()的第一个参数中,可以输入\1、\2、\3.....表示“在替换中输入分组1,2,3...的文本。

#例如,假定想要隐去密探的姓名,只显示他们姓名的第一个字母。要做到这一点,可以使用正则表达式Agent(\w)\w*,传入r'\I****'作为sub()的第一个参数。

#字符串中的\I将由分组1匹配的文本所替代,也就是正则表达式的(\w)分组。

agentNamesRegex=re.compile(r'Agent (\w)\w*')

agentNamesRegex.sub(r'\1****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')

#'A**** told C**** that E**** knew B**** was a double agent.'

#管理复杂的正则表达式

#如果需要匹配复杂的文本模式,可能需要长的、费解的正则表达式。

#可以通过向re.compile()传入变量re.VERBOSE作为第二个参数,告诉re.compile()忽略正则表达式字符串中的空白符和注释。

#现在,不必使用这样难以阅读的正则表达式。

phoneRegex=re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')

#你可以将正则表达式放在多行中,并加上注释:

phoneRegex=re.compile(r'''(

(\d{3}|\(\d{3}\))?   #area code

(\s|-|\.)?           #separator

\d{3}                #first 3 digits

(\s|-|\.)            #separator

\d{4}                #last 4 digits

(\s*(ext|x|ext.)s*\d{2,5})?    #extension

)''',re.VERBOSE)

#组合使用re.IGNORECASE ,re.DOTALL和re.VERBOSE 

#如果你希望在正则表达式中使用re.VERBOSE来编写注释,还希望用re.IGNORECASE来忽略大小写,该怎么办?

#遗憾的是,re.compile()函数只能接收一个值作为它的第二个参数。可以使用管道字符(|)将变量组合起来,从而绕过这个限制。管道字符在这里称为“按位或”操作符。

#如果希望正则表达式不区分大小写,并且句点字符匹配换行,就可以这样构造re.compile()调用:

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL)

#使用第二个参数的全部3个选项:

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL|re.VERBOSE)

#编译

#当我们在python 中使用正则表达式时,re模块内部会干两件事:

#1.编译正则表达式,如果正则表达式的字符串本身不合法,会报错

#2.用编译后的正则表达式去匹配字符串。

#如果一个正则表达式要重复使用几千次,出于效率考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配

re_telephone=re.compile(r'^(\d{3})-(\d{3,8})$')

re_telephone.match('010-12345').groups()

re_telephone.match('010-8086').groups()

 

#!usr/bin/env python3

#-*- coding:utf-8 -*-

import re 

# re.match('re_expression','strings')  match中的正则表达式会从给定字符串的第一个字符开始匹配,如果前面N个字符不符合,则返回None,否则返回匹配的字符串,match()只返回满足字符串中第一个满足表达式的子串

re_m = re.match(r'\d{3}-d','010-12345')

re_text = re_m.group(0)

#'010-1

re_m2 = re.match(r'\s\d{3}-d','010-12345')

#re_m2的值为None

match后的结果用group()来获取, group()等于group(0)返回满足整个正则表达式的字符串, group(1),返回表达式中的第一个分组的内容,group(2)返回第二个分组的内容,groups()返回分组1,分组2,。。组成的一个元组

mol = re.compile(r'(\d{3}\w([.A-F]{2,4})[F-Z]{2})')

#mol.search('strings') 与 match相比,search可以从内容的中间开始匹配,其他的同match,只返回第一个满足的子串

mol.search('asd123A.EVU23').group()

#'123A.EVU'

#findall 与search,match相比,查找时可以从内容的任意位置开始,也可以返回所有的 符合的子串

mo1=re.compile(r'''(\d{3}\w{2}([.A-F]{2,4})[%@F-Z]{3})''',re.VERBOSE)

A = mo1.findall('576dfCD.HIS794SDABC@KM')

#[('576dfCD.HIS','CD.'),('794SDABC@KM','ABC')]

compile()的第二个参数,可以设定正则表达式的一些特性

re.VERBOSE                                  用于忽视正则表达式中的 空白符和注释

re.I或re.IGNORECASE                 让正则表达式忽视大小写

re.DOTALL                                    让正则中的句点符匹配所有的字符,包括换行符

如果需要同时使用多个特性,可以用|连接多个特性值

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL)

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL|re.VERBOSE)

使用正则表达式分割字符串

re.split(r'\s+','a b  c')

#['a','b','c']

使用正则表达式匹配需替换的字符串

namesRegex=re.compile(r'Agent \w+')

namesRegex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')

#'CENSORED gave the secret documents to CENSORED.'

#正则表达式

#在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母、数字或下划线 . 英文点号可以匹配任意单个字符,换行符除外。

#\s 可以匹配一个空格(也包括Tab等空白符),对于特殊字符- ,在正则表达式中要用转义字符\转义。

#\D 匹配除0到9的数字以外的任何字符 ,\W 匹配除数字、字母和下划线以外的任何字符,\S 匹配除空格、制表符和换行符以外的任何字符

#变长字符:表示匹配前一个字符的次数   *表示0个或多个字符  + 表示至少一个字符,?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

#\d{3}\s+\d{3,8} 表示匹配3个数字和一个或多个空格和3-8个数字

#中括号[]可以自定义匹配范围,表示可以是里面的任意一个

#[a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个数字、字母或下划线组成的字符串,也就是Python合法的变量。

#A|B可以匹配A或B,所以 (P|p)ython 可以匹配Python 或 python .

#^表示行的开头,^\d 表示必须以数字开头。 $表示行的结束,\d$表示必须以数字结束。

#py也可以匹配python,但是加上^py$就变成了整行匹配,就只能匹配py了。

#在字符串前加上r,表示对立面的字符不转义。

import re 

re.match(r'^\d{3}\-\d{3,8}$','010-12345') 

re.match(r'^\d{3}\-\d{3,8}$','010 12345')

#match()方法判断是否匹配,如果匹配成功,返回一个match对象,否则返回None.

#经Python3.5测试,只有res2有匹配到值,res1,res3都返回None。match是根据匹配模式从给定字符串的第一个字符开始匹配,如果第一个字符就不符合,则返回None

'''

>>> pattern=re.compile(r'hello')

>>> res1=re.match(pattern,'hell')

>>> res2=re.match(pattern,'hellow')

>>> res3=re.match(pattern,'ashello')

>>> res1

>>> res2

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

>>> res3

'''

# 分组

# 除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group).比如 ^(\d{3})-(\d{3,8})$分别定义了两个组,

#可以直接从匹配的字符串中提取出区号和本地号码:

m=re.match(r'^(\d{3})-(\d{3,8})$','010-12345')

print(m.group(0),

m.group(1),

m.group(2))

#010-12345 010 12345

#group(0)永远是原始字符串,group(1)、group(2)……表示第1/2、……个子串。

#贪婪匹配

#正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。例,匹配出数字后面的0:

re.match(r'^(\d+)(0*)$','102300').groups()

#('102300', '')

#由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。

re.match(r'^(\d+?)(0*)$','1022300300').groups()

#('10223003', '00')

'''

import re 

mo1=re.compile(r'''(\d{3}\w{2}([.A-F]{2,4})[%@F-Z]{3})''',re.VERBOSE)

A = mo1.findall('576dfCD.HIS794SDABC@KM')

for n in A:

    print(n[0])

'''

#用管道“|”匹配多个分组。

#希望匹配许多表达式中的一个时,可以用它

#如r'Batman|Tina Fey'将匹配‘Batman或Tian Fey .如果Batman和Tina Fey 都出现在被查找的字符串中,第一次出现的匹配文本将作为Match对象返回。

heroRegex=re.compile(r'Batman|Tina Fey')

mo1=heroRegex.search('Batman and Tina Fey.')

print(mo1.group())

#Batman

#也可以使用管道来匹配多个模式中的一个,作为正则表达式的一部分。

#比如你希望匹配Batman,Batmobile,Batcopter和Batbat中任意一个。

batRegex=re.compile(r'Bat(man|mobile|copter|bat)')

mo=batRegex.search('Batmobile lost a wheel')

#点-星将匹配除除换行符外的所有字符。

#通过传入re.DOTALL作为re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行符。

noNewlineRegex=re.compile('.*')

m='Serve the public trust.\nProtect the innocent.\nUphold the law.'

n=noNewlineRegex.search(m).group()

print(n)

#'Serve the public trust.'

newlineRegex=re.compile('.*',re.DOTALL)

print(newlineRegex.search(m).group())

'''

Serve the public trust.

Protect the innocent.

Uphold the law.

'''

#不区分大小写的匹配,可以向re.compile()传入re.IGNORECASE或re.I,作为第二个参数。

robocop=re.compile(r'robocop',re.I)

robocop.search('Robocop is part man,part machine,all cop.').group()

#'Robocop'

#用sub()方法替换字符串

#正则表达式不仅能找到文本模式,而且能够用新的文本替换掉这些模式。

#Regex对象的sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式。sub()方法

#返回替换完成后的字符串。

namesRegex=re.compile(r'Agent \w+')

namesRegex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')

#'CENSORED gave the secret documents to CENSORED.'

#有时候,你可能需要使用匹配的文本本身,作为替换的一部分,在sub()的第一个参数中,可以输入\1、\2、\3.....表示“在替换中输入分组1,2,3...的文本。

#例如,假定想要隐去密探的姓名,只显示他们姓名的第一个字母。要做到这一点,可以使用正则表达式Agent(\w)\w*,传入r'\I****'作为sub()的第一个参数。

#字符串中的\I将由分组1匹配的文本所替代,也就是正则表达式的(\w)分组。

agentNamesRegex=re.compile(r'Agent (\w)\w*')

agentNamesRegex.sub(r'\1****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')

#'A**** told C**** that E**** knew B**** was a double agent.'

#管理复杂的正则表达式

#如果需要匹配复杂的文本模式,可能需要长的、费解的正则表达式。

#可以通过向re.compile()传入变量re.VERBOSE作为第二个参数,告诉re.compile()忽略正则表达式字符串中的空白符和注释。

#现在,不必使用这样难以阅读的正则表达式。

phoneRegex=re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')

#你可以将正则表达式放在多行中,并加上注释:

phoneRegex=re.compile(r'''(

(\d{3}|\(\d{3}\))?   #area code

(\s|-|\.)?           #separator

\d{3}                #first 3 digits

(\s|-|\.)            #separator

\d{4}                #last 4 digits

(\s*(ext|x|ext.)s*\d{2,5})?    #extension

)''',re.VERBOSE)

#组合使用re.IGNORECASE ,re.DOTALL和re.VERBOSE 

#如果你希望在正则表达式中使用re.VERBOSE来编写注释,还希望用re.IGNORECASE来忽略大小写,该怎么办?

#遗憾的是,re.compile()函数只能接收一个值作为它的第二个参数。可以使用管道字符(|)将变量组合起来,从而绕过这个限制。管道字符在这里称为“按位或”操作符。

#如果希望正则表达式不区分大小写,并且句点字符匹配换行,就可以这样构造re.compile()调用:

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL)

#使用第二个参数的全部3个选项:

someRegexValue=re.compile('foo',re.IGNORECASE|re.DOTALL|re.VERBOSE)

#编译

#当我们在python 中使用正则表达式时,re模块内部会干两件事:

#1.编译正则表达式,如果正则表达式的字符串本身不合法,会报错

#2.用编译后的正则表达式去匹配字符串。

#如果一个正则表达式要重复使用几千次,出于效率考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配

re_telephone=re.compile(r'^(\d{3})-(\d{3,8})$')

re_telephone.match('010-12345').groups()

re_telephone.match('010-8086').groups()

猜你喜欢

转载自www.cnblogs.com/ein-key5205/p/12315200.html