Python正则表达式入门进阶

栏目: Python · 发布时间: 6年前

内容简介:1.Python正则表达式模块1.1 正则表达式处理字符串主要有四大功能1.匹配 查看一个字符串是否符合正则表达式的语法,一般返回true或者false

1.Python正则表达式模块

1.1 正则表达式处理字符串主要有四大功能

1.匹配 查看一个字符串是否符合正则表达式的语法,一般返回true或者false

2.获取 正则表达式来提取字符串中符合要求的文本

3.替换 查找字符串中符合正则表达式的文本,并用相应的字符串替换

4.分割 使用正则表达式对字符串进行分割。

1.2 Python 中re模块使用正则表达式的两种方法

1.使用re.compile(r,f)方法生成正则表达式对象,然后调用正则表达式对象的相应方法。这种做法的好处是生成正则对象之后可以多次使用。

2.re模块中对正则表达式对象的每个对象方法都有一个对应的模块方法,唯一不同的是传入的第一个参数是正则表达式字符串。此种方法适合于只使用一次的正则表达式。

1.3 正则表达式对象的常用方法

1. rx.findall(s,start, end):

返回一个列表,如果正则表达式中没有分组,则列表中包含的是所有匹配的内容,如果正则表达式中有分组,则列表中的每个元素是一个元组,元组中包含子分组中匹配到的内容,但是没有返回整个正则表达式匹配的内容

2. rx.finditer(s, start, end):

返回一个可迭代对象

对可迭代对象进行迭代,每一次返回一个匹配对象,可以调用匹配对象的group()方法查看指定组匹配到的内容,0表示整个正则表达式匹配到的内容

3. rx.search(s, start, end):

返回一个匹配对象,倘若没匹配到,就返回None

search方法只匹配一次就停止,不会继续往后匹配

4. rx.match(s, start, end):

如果正则表达式在字符串的起始处匹配,就返回一个匹配对象,否则返回None

5. rx.sub(x, s, m):

返回一个字符串。每一个匹配的地方用x进行替换,返回替换后的字符串,如果指定m,则最多替换m次。对于x可以使用/i或者/g

6. rx.subn(x, s, m):

与re.sub()方法相同,区别在于返回的是二元组,其中一项是结果字符串,一项是做替换的个数。

7. rx.split(s, m):

分割字符串,返回一个列表,用正则表达式匹配到的内容对字符串进行分割

如果正则表达式中存在分组,则把分组匹配到的内容放在列表中每两个分割的中间作为列表的一部分,如:

rx = re.compile(r"(\d)[a-z]+(\d)")

s = "ab12dk3klj8jk9jks5"

result = rx.split(s)

返回['ab1', '2', '3', 'klj', '8', '9', 'jks5']

8. rx.flags():正则表达式编译时设置的标志

9. rx.pattern():正则表达式编译时使用的字符串

1.4 匹配对象的属性与方法

01. m.group(g, ...)

返回编号或者组名匹配到的内容,默认或者0表示整个表达式匹配到的内容,如果指定多个,就返回一个元组

02. m.groupdict(default)

返回一个字典。字典的键是所有命名的组的组名,值为命名组捕获到的内容

如果有default参数,则将其作为那些没有参与匹配的组的默认值。

03. m.groups(default)

返回一个元组。包含所有捕获到内容的子分组,从1开始,如果指定了default值,则这个值作为那些没有捕获到内容的组的值

04. m.lastgroup()

匹配到内容的编号最高的捕获组的名称,如果没有或者没有使用名称则返回None(不常用)

05. m.lastindex()

匹配到内容的编号最高的捕获组的编号,如果没有就返回None。

06. m.start(g):

当前匹配对象的子分组是从字符串的那个位置开始匹配的,如果当前组没有参与匹配就返回-1

07. m.end(g)

当前匹配对象的子分组是从字符串的那个位置匹配结束的,如果当前组没有参与匹配就返回-1

08. m.span()

返回一个二元组,内容分别是m.start(g)和m.end(g)的返回值

09. m.re()

产生这一匹配对象的正则表达式

10. m.string()

传递给match或者search用于匹配的字符串

11. m.pos()

搜索的起始位置。即字符串的开头,或者start指定的位置(不常用)

12. m.endpos()

搜索的结束位置。即字符串的末尾位置,或者end指定的位置(不常用)

1.5 总结

1.对于正则表达式的匹配功能,Python没有返回true和false的方法,但可以通过对match或者search方法的返回值是否是None来判断

2.对于正则表达式的搜索功能,如果只搜索一次可以使用search或者match方法返回的匹配对象得到,对于搜索多次可以使用finditer方法返回的可迭代对象来迭代访问

3.对于正则表达式的替换功能,可以使用正则表达式对象的sub或者subn方法来实现,也可以通过re模块方法sub或者subn来实现,区别在于模块的sub方法的替换文本可以使用一个函数来生成

4.对于正则表达式的分割功能,可以使用正则表达式对象的split方法,需要注意如果正则表达式对象有分组的话,分组捕获的内容也会放到返回的列表中

2 正则匹配与替换

1.python里使用正则表达式的组匹配自引用

在前面学习过组的匹配,也就是一个括号包含就叫做一个组。在一个复杂一点的正则表达式里,比如像(1)(2)(3)这样,就匹配三组,如果想在这个表达式里引用前面匹配的组,怎么办呢?其实最简单的方式是通过组号来引用,比如像(1)(2)(3)——\1。使用“\num”的语法来自引用,如下例子:

#python 3.6

#

import re

address = re.compile(

r'''

# The regular name

(\w+)              # first name

\s+

(([\w.]+)\s+)?      # optional middle name or initial

(\w+)              # last name

\s+

<

# The address: first_name.last_name@domain.tld

(?P<email>

\1              # first name

\.

\4              # last name

@

([\w\d.]+\.)+    # domain name prefix

(com|org|edu)    # limit the allowed top-level domains

)

>

''',

re.VERBOSE | re.IGNORECASE)

candidates = [

u'First Last <first.last@example.com>',

u'Different Name <first.last@example.com>',

u'First Middle Last <first.last@example.com>',

u'First M. Last <first.last@example.com>',

]

for candidate in candidates:

print('Candidate:', candidate)

match = address.search(candidate)

if match:

print('  Match name :', match.group(1), match.group(4))

print('  Match email:', match.group(5))

else:

print('  No match')

结果输出如下:

Candidate: First Last <first.last@example.com>

Match name : First Last

Match email: first.last@example.com

Candidate: Different Name <first.last@example.com>

No match

Candidate: First Middle Last <first.last@example.com>

Match name : First Last

Match email: first.last@example.com

Candidate: First M. Last <first.last@example.com>

Match name : First Last

Match email: first.last@example.com

在这个例子里,就引用了第1组first name和第4组last name的值,实现了前后不一致的EMAIL的姓名,就丢掉它。

2.python里使用正则表达式的组匹配通过名称自引用

在前学习过正则表达式的组可以通过组号来自引用,看起来使用很简单的样子,其实它还是不容易维护的,比如你某一天需要在这个正则表达式里插入一个组时,就发现后面的组号全打乱了,因此需要一个一个地更改组号,有没有更容易维护的方式呢?是有的,就是使用组名称来引用。如下面的例子:

#python 3.6

#

import re

address = re.compile(

'''

# The regular name

(?P<first_name>\w+)

\s+

(([\w.]+)\s+)?      # optional middle name or initial

(?P<last_name>\w+)

\s+

<

# The address: first_name.last_name@domain.tld

(?P<email>

(?P=first_name)

\.

(?P=last_name)

@

([\w\d.]+\.)+    # domain name prefix

(com|org|edu)    # limit the allowed top-level domains

)

>

''',

re.VERBOSE | re.IGNORECASE)

candidates = [

u'cai junsheng <cai.junsheng@example.com>',

u'Different Name <cai.junsheng@example.com>',

u'Cai Middle junsheng <cai.junsheng@example.com>',

u'Cai M. junsheng <cai.junsheng@example.com>',

]

for candidate in candidates:

print('Candidate:', candidate)

match = address.search(candidate)

if match:

print('  Match name :', match.groupdict()['first_name'],

end=' ')

print(match.groupdict()['last_name'])

print('  Match email:', match.groupdict()['email'])

else:

print('  No match')

结果输出如下:

Candidate: cai junsheng <cai.junsheng@example.com>

Match name : cai junsheng

Match email: cai.junsheng@example.com

Candidate: Different Name <cai.junsheng@example.com>

No match

Candidate: Cai Middle junsheng <cai.junsheng@example.com>

Match name : Cai junsheng

Match email: cai.junsheng@example.com

Candidate: Cai M. junsheng <cai.junsheng@example.com>

Match name : Cai junsheng

Match email: cai.junsheng@example.com

在这个例子里,就是通过(?P=first_name)引用。

3.python里使用正则表达式的组匹配是否成功之后再自引用

在前面学习了通过名称或组号来引用本身正则表达式里的组内容,可以实现前后关联式的相等判断。如果再更进一步,比如当前面组匹配成功之后,就选择一种模式来识别,而不匹配成功又选择另外一种模式进行识别,这相当于if...else...语句的选择。我们来学习这种新的语法:(?(id)yes-expression|no-expression)。其中id是表示组名称或组编号, yes-expression是当组匹配成功之后选择的正则表达式,而no-expression 是不匹配成功之后选择的正则表达式。如下例子:

#python 3.6

#

import re

address = re.compile(

'''

^

# A name is made up of letters, and may include "."

# for title abbreviations and middle initials.

(?P<name>

([\w.]+\s+)*[\w.]+

)?

\s*

# Email addresses are wrapped in angle brackets, but

# only if a name is found.

(?(name)

# remainder wrapped in angle brackets because

# there is a name

(?P<brackets>(?=(<.*>$)))

|

# remainder does not include angle brackets without name

(?=([^<].*[^>]$))

)

# Look for a bracket only if the look-ahead assertion

# found both of them.

(?(brackets)<|\s*)

# The address itself: username@domain.tld

(?P<email>

[\w\d.+-]+      # username

@

([\w\d.]+\.)+    # domain name prefix

(com|org|edu)    # limit the allowed top-level domains

)

# Look for a bracket only if the look-ahead assertion

# found both of them.

(?(brackets)>|\s*)

$

''',

re.VERBOSE)

candidates = [

u'Cai junsheng <Cai.junsheng@example.com>',

u'No Brackets first.last@example.com',

u'Open Bracket <first.last@example.com',

u'Close Bracket first.last@example.com>',

u'no.brackets@example.com',

]

for candidate in candidates:

print('Candidate:', candidate)

match = address.search(candidate)

if match:

print('  Match name :', match.groupdict()['name'])

print('  Match email:', match.groupdict()['email'])

else:

print('  No match')

结果输出如下:

Candidate: Cai junsheng <Cai.junsheng@example.com>

Match name : Cai junsheng

Match email: Cai.junsheng@example.com

Candidate: No Brackets first.last@example.com

No match

Candidate: Open Bracket <first.last@example.com

No match

Candidate: Close Bracket first.last@example.com>

No match

Candidate: no.brackets@example.com

Match name : None

Match email: no.brackets@example.com

在这里,当name组出现时才会寻找括号< >,如果括号不成对就不匹配成功;如果name组不出现,就不需要括号,因此选择了另一个正则表达式。

4.python里使用正则表达式来替换匹配成功的组

在前面主要学习了怎么样匹配成功,都没有修改原来的内容的。现在来学习一个匹配成功之后修改相应的内容,在这里使用sub()函数来实现这个功能,同时使用引用组号来插入原来的字符,例子如下:

#python 3.6

#

import re

bold = re.compile(r'\*{2}(.*?)\*{2}')

text = 'Make this **cai**.  This **junsheng**.'

print('Text:', text)

print('Bold:', bold.sub(r'<b>\1</b>', text))

结果输出如下:

Text: Make this **cai**.  This **junsheng**.

Bold: Make this <b>cai</b>.  This <b>junsheng</b>.

5.python里使用正则表达式来替换匹配成功的组名

在前面学习了找到组之后,通过组序号来替换,比如像bold.sub(r'\1', text)),这里是通过\1来替换的,这样的方式就是简单,快捷。但是不方便维护,不方便记忆,要想把这点改进一下,就得使用组名称的方式来替换,就跟前面学习组名称匹配一样,给一个组起一个名称,也像为什么给每一个人起一个名称一样,方便区分和记忆。因此使用这样的语法:\g

#python 3.6

#

import re

bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')

text = 'Make this **cai**.  This **junsheng**.'

print('Text:', text)

print('Bold:', bold.sub(r'<b>\g<bold_text></b>', text))

结果输出如下:

Text: Make this **cai**.  This **junsheng**.

Bold: Make this <b>cai</b>.  This <b>junsheng</b>.

6.python里使用正则表达式来替换匹配成功的组并限定替换的次数

在前面学习过通过组名称来替换原来的字符串,这种替换只要出现相同的匹配成功,就会替换,而不管出现多少次。如果有一天,项目经理说要只需要替换第一个,或者前5个,怎么办呢?哈哈,这时你就得使用sub函数的count参数了,它可以指定替换的次数,轻松地解决了问题,例子如下:

#python 3.6

#

import re

bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')

text = 'Make this **cai**.  This **junsheng**.'

print('Text:', text)

print('Bold:', bold.sub(r'<b>\g<bold_text></b>', text, count=1))

结果输出如下:

Text: Make this **cai**.  This **junsheng**.

Bold: Make this <b>cai</b>.  This **junsheng**.

7.python里使用正则表达式来替换匹配成功的组并输出替换的次数

在前面我们学习过怎么样限制替换的次数,如果我们想知道正则表达式里匹配成功之后,替换字符串的次数,那么需要怎么办呢?这是一个好问题,这时就需要采用另一个外函数subn()了。这个函数不但输出替换后的内容,还输出替换的次数,例子:

#python 3.6

#

import re

bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')

text = 'Make this **cai**.  This **junsheng**.'

print('Text:', text)

print('Bold:', bold.subn(r'<b>\g<bold_text></b>', text))

结果输出如下:

Text: Make this **cai**.  This **junsheng**.

Bold: ('Make this <b>cai</b>.  This <b>junsheng</b>.', 2)

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-11/155345.htm


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据结构

数据结构

霍罗威茨 / 机械工业出版社 / 2006-7-1 / 48.00元

《数据结构》(C语言版)针对采用ANSI C实现数据结构进行了全面的描述和深入的讨论。书中详细讨论了栈、队列、链表以及查找结构、高级树结构等功能,对裴波那契堆、伸展树、红黑树、2-3树、2-3-4树、二项堆、最小-最大堆、双端堆等新的数据结构进行了有效分析。《数据结构》(C语言版)对一些特殊形式的堆结构,诸如应用在双端优先队列中的最小-最大堆和双端堆的数据结构以及左高树、裴波那契堆、二项堆等数据结......一起来看看 《数据结构》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具