Python基础学习之正则表达式(完整版)

Python基础学习之正则表达式

1. python 中的正则匹配步骤

  1. 用import re 导入正则表达式模块;

  2. 用re.compile() 创建一个regex对象,最好使用原始字符串;即在字符串前加r;

  3. 向regex对象的search() 中传入想查找的字符串。返回值为一个Match对象;

  4. 调用Match对象的group() 方法,返回实际匹配文本字符串;

例子:寻找电话号码

import re

phoneNumRegex = re.compile(r'\d{3}-\d{3}-\d{4}')
mo = phoneNumRegex.search('My phone number is 333-333-2222.')
print('Number is :' + mo.group())    # 输出:333-333-2222

2. 常用的匹配模式

2.1 利用括号进行分组;

import re

phoneNumRegex = re.compile(r'(\d{3})-(\d{3}-\d{4})')  # 使用括号,第一个括号内是第一组,第二个括号内是第二组;
mo = phoneNumRegex.search('My phone number is 333-333-2222.')
print('Number is :' + mo.group(0))   # 返回整个匹配文本;输出:Number is :333-333-2222
print('Number is :' + mo.group())  # group()中传入0,或者不传入,则返回整个匹配文本
print('Area Number is :' + mo.group(1))  # group()中传入1,返回第一个括号内的匹配值;输出:Area Number is :333
print('Phone Number is :' + mo.group(2))  # group()中传入2,返回第一个括号内的匹配值;输出:Phone Number is :333-2222
print(mo.groups())  # 使用gourps()  一次返回所有括号内的匹配结果;输出:('333', '333-2222')
areaNum, ThoneNum = mo.groups()  # 多重赋值技巧
print(areaNum, ThoneNum)   # 输出:333 333-2222

phoneNumRegex = re.compile(r'(\(\d{3}\))-(\d{3}-\d{4})')  # 当匹配值中有括号时,使用 \( 和 \) 进行转义;
mo = phoneNumRegex.search('My phone number is (333)-333-2222.')
print('Number is :' + mo.group())  # 输出:Number is :(333)-333-2222

2.2 使用管道符(|)匹配多个分组; | 相当于或运算;但只返回第一个匹配到的值;

import re
HeroRegex=re.compile(r'batman|superman')   # 匹配 batman 或者 superman;
mo1=HeroRegex.search('batman and superman!')
print(mo1.group())    # 输出管道符中第一个匹配项;输出:batman
mo2=HeroRegex.search('superman and batman!')
print(mo2.group())    # 输出管道符中第一个匹配项;输出:superman

2.3 使用问号 (?) 实现可选匹配

使用 ? 表明?前面的分组是可选的,即匹配?前面的分组 零次 或者 一次,举例如下:

import re
BatRegex=re.compile(r'bat(wo)?man')
mo1=BatRegex.search('batman and batwoman')
print(mo1.group())
mo2=BatRegex.search('batwoman and batman')
print(mo2.group())

2.4 用星号(*) 匹配零次,一次或者多次

使用 * 可以匹配 * 前面的分组零次,一次或者多次,举例如下:

import re
BatRegex=re.compile(r'bat(wo)*man')
mo1=BatRegex.search('batman and batwoman')
print(mo1.group())
mo2=BatRegex.search('batwoman and batman')
print(mo2.group())
mo3=BatRegex.search('batwowowowowowoman and batman')
print(mo3.group())

2.5 使用加号(+)匹配 一次 或者 多次;

使用加号 + 匹配+前面的分组 一次或者多次,若一次都没有出现,则匹配结果为None;

import re
BatRegex=re.compile(r'bat(wo)+man')
mo1=BatRegex.search('batman and batwoman')
print(mo1.group())
mo2=BatRegex.search('batman')
print(mo2==None)   # 返回 True

2.6 使用花括号 {} 匹配指定次数;

使用花括号{}, {3}前面的分组重复3次;{3,5} 前面的分组重复 3-5次;{3,}前面的分组3到无限大次;

扫描二维码关注公众号,回复: 11940136 查看本文章
import re
BatRegex=re.compile(r'bat(wo){3}man')
mo1=BatRegex.search('batman and batman')
print(mo1==None)
mo2=BatRegex.search('batwowowoman')
print(mo2.group())

2.7 贪心匹配 & 非贪心匹配

当{3,5},即匹配三次,四次,五次 都可以,那么 Python会匹配尽量多的次数,例如, Batwowowowowoman, 使用 BatRegex=re.compile(r’(wo){3,5}’),那么Python会自动匹配最多的次数,即wowowowowo, 那么如何可以匹配少的次数呢;我们使用问好(?),即BatRegex=re.compile(r’(wo){3,5}?’) ,则返回wowowo;

import re
BatRegex=re.compile(r'(wo){3,5}')
mo1=BatRegex.search('batman and batwowowowowoman')
print(mo1.group())
BatRegex2=re.compile(r'(wo){3,5}?')
mo2=BatRegex2.search('batman and batwowowowowoman')
print(mo2.group())

3. Findall() 方法

Regex 的另一个方法是findall(),可以返回一组字符串,包含所有满足条件的匹配项;

正则表达式没有分组,则返回一个字符串列表;

正则表达式有分组,返回元组的列表,每个元组表示一个匹配;

import re
phoneNumRegex=re.compile(r'\d\d\d-\d\d\d\d-\d\d\d\d')
print(phoneNumRegex.findall('kai:199-1982-1222; Pi:178-1982-1223'))   #返回 ['199-1982-1222', '178-1982-1223']
phoneNumRegex2=re.compile(r'(\d\d\d)-(\d\d\d\d-\d\d\d\d)')
print(phoneNumRegex2.findall('kai:199-1982-1222; Pi:178-1982-1223'))   #返回  [('199', '1982-1222'), ('178', '1982-1223')]

4. 字符匹配

4.1 字符分类

'''
\d    表示 0-9 的任何数字

\D    表示除了0-9 的任何字符

\w    表示任何字母,数字或者下划线字符

\w    表示除了 字母,数字 或者下划线 的字符

\s    表示 空格  制表符或者换行

\S    表示除 空格,制表符,换行之外的字符
'''

4.2 建立自己的字符分类

使用上述字符分类大广泛的话,可以自定义字符分类,方法是使用 [],比如要匹配元音字母,使用[aeiouAEIOU],还可以使用 [0-5] 表示0到5的数字;并且 [] 中不需要使用\来取反义; 在[]最开始使用^ ,表示除 [] 中之外的字符;例如: [^AEIOUaeiou] ; 表示除 [aeiouAEIOU] 之外的字符;

4.3 插入字符和美元字符

可以在正则表达式开始的地方使用插入符号(^),表明匹配必须发生在被查找文本开始处。类似的 正则表达式最后使用 $, 表示文本结束;

举例: r’\d+$’ 表示 从开始到结束都是数字的字符串。

import re
phoneNumRegex=re.compile(r'^\d+$')
print(phoneNumRegex.findall('1234567 345')==[]) # 无论是哪里有非数字的字符,都会返回[];
print(phoneNumRegex.findall('1234455'))

4.4 通配字符

正则表达式中,. (句号)代表通配符, 匹配除了换行外的所有字符(只匹配一个字符);使用真正的. 需要使用转义(.);
通过传入 re.DOTALL 作为re.compile() 的第二个参数,可以使. 匹配所有字符,包括换行符;

import re
noNewLineRegex=re.compile('.*')
newLineRegex=re.compile('.*',re.DOTALL)
mo=noNewLineRegex.search('So ,god bless American.\n God do not bless American.')
mo1=newLineRegex.search('So ,god bless American.\n God do not bless American.')
print("----")
print(mo.group())
print("----")
print(mo1.group())

4.5 点星(.*)符号

使用 .* 代表任意字符;

import re
nameRegex=re.compile(r'first name:(.*) last name:(.*)')
mo=nameRegex.search('first name:zhang last name: Kai')
print(mo.group())   # 返回:first name:zhang, last name: Kai

贪心模式 & 非贪心模式(使用?)

import re
nonGreedyRegex=re.compile(r'<.*?>')   # 非贪心模式
GreedyRegex=re.compile(r'<.*>')   # 贪心模式
mo=nonGreedyRegex.search('<first name:zhang> last name: Kai>')
mo2=GreedyRegex.search('<first name:zhang> last name: Kai>')
print(mo.group())   # 返回:<first name:zhang>
print(mo2.group())    #返回:<first name:zhang> last name: Kai>

5. 第二参数 re.I

RE.compile()的第二参数;

6. 正则表达式命名分组

命名方式: ?P<名称>
举例:(?P\d{4}) 匹配一个四位数字,名字为year;

猜你喜欢

转载自blog.csdn.net/weixin_47139649/article/details/108774563
今日推荐