python的Re模块学习

本文初步介绍 正则表达式的定义,分类的组成部分。并举例编码


一、什么是正则表达式

答:在unix系统中,用来表示规则的字符串。在开发语言中需要处理大量的字符串,引入了这个规则。

字符串的处理:

1. 过滤字符串,在字符串中获取需要的部分

2. 验证字符的输入是否符合规范, 例如用户名,密码的验证

3. 切割字符串, 划分字符内容

4. 替换字符串, 替换文本内容的信息。

二、正则表达式的分类

目前产雇佣的两大正则系统: POSIX系统, Pcre系统。

开发语言  Perl  --> Pcre

C --> POSIX

PHP --> POSIX, Pcre

Python --> Pcre

三、正则表达式的内容

可以划分为三个部分,原子,元字符和模式修正符

原子:是正则表达式的最小单元。所有的字符都是原子。 包括可见字符: 1-9,a-z,&*等。

不可见字符: \n, \r , \v , \t, \f等

元字符: 原子修饰符。 修饰原子。 可以划分为, 整体修饰,数量修饰,位置修饰和特殊修饰(转义,词边界等)。

模式修正符: 对正则表达式进行一些额外的匹配规则 。

3.1、 原子

原子:正则表达式的最小单元所有的字符都是原子。 包括可见字符: 1-9,a-z,&*等。

不可见字符: \n, \r , \v , \t, \f等。

需要学习的是有 7个专用的转义字符:

原子的转义字符
\d: 表示数字 0-9
\D: 表示除了 数字 0-9 以外的字符
\s :表示任意空白字符(不可见,例如空格,换行。 \n,\r)
\S: 表示除了空白字符以外的 任意字符
\w: 表示a-z,0-9,A-Z,_ 。 即常用的变量名元素
\W:表示除了 [a-z0-9A-Z_] 以外的任意字符
. : 表示除了\n以 的任意字符

import re  # 导入 re模块

#### 正则表达式的应用测试步骤
# 1. 定义 正则表达式
# 2. 定义 检查字符
# 3. 检查


# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):

    res = re.search(pattern,str1)

    print(type(res), res)


#####################################

pattern1 = 'a'
str1 = '13afas'
res = re.search(pattern1,str1)
print(type(res), res)  #  


pattern2 = '\d'   # 0-9 纯数字
str ='abc,123'
res = re.search(pattern2,str)
print(type(res), res) #  


pattern2 = '\D'   # 除了0-9 以外的任意字符
str ='abc,123'
res = re.search(pattern2,str)
print(type(res), res) #  


pattern2 = '\D'   # 除了0-9 以外的任意字符
str ='=bc,123'
res = re.search(pattern2,str)
print(type(res), res) #  


pattern2 = '\w'   # 0-9,a-z,A-Z,_  . 即我们常用的变量命名元素
str ='=bc,123'
run(pattern2,str) #  


pattern2 = '\w'   # 0-9,a-z,A-Z,_  . 即我们常用的变量命名元素
str ='_bc,123'
run(pattern2,str) #  


pattern2 = '\W'   # 除0-9,a-z,A-Z,_ 以外的元字符  
str ='_A1bc,123'
run(pattern2,str) #  


pattern2 = '\s'   # \s 空白字符, 包括换行, 换行在不同的系统是不一样的。 \n,\r,\v,\f
str ='1 234 abc'
run(pattern2,str) #  


pattern2 = '\s'   # \s 空白字符, 包括换行, 换行在不同的系统是不一样的。 \n,\r,\v,\f

str ='1234\nabc'

run(pattern2,str) #  


pattern2 = '\s'   # \s 空白字符, 包括换行, 换行在不同的系统是不一样的。 \n,\r,\v,\f
str ='1234\rabc'
run(pattern2,str) #  


pattern2 = '\S'   # 空白以外的字符
str ='  1234\nabc'
run(pattern2,str) #  


pattern2 = '\S'   # 空白以外的字符
str ='\r\v\f\nabc'
run(pattern2,str) #  


pattern2 = '.'   # 任意字符, 除了换行符 .
str ='abc'
run(pattern2,str) #  


pattern2 = '.'   # 任意字符, 除了换行符 .
str ='1bc'
run(pattern2,str) #  


pattern2 = '.'   # 任意字符, 除了换行符 .
str ='_bc'
run(pattern2,str) #  


pattern2 = '.'   # 任意字符, 除了换行符 .
str ='\nbc'
run(pattern2,str) #  

3.2、元字符

原子修饰符。 修饰原子。 可以划分为, 整体修饰,数量修饰,位置修饰和特殊修饰(转义,词边界等

3.2.1 整体修饰:

[] : 原子列表。 将多个原子用 [] 包裹表示,满足里面任意个元素即可。

[^] : 排除 原子列表中的元素。

import re

# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)


patten1 = '[a,b,1,2,A,Z]'
str1 = 'cd1BC'
str2 = 'BCDS'
str3 = 'ab85967'
run(patten1, str1) #  
run(patten1, str2) #  None
run(patten1, str3) #  


pattern2 = '[^0,1,2]' # 除了 012以外的任意 原子
str1 = '012AZ'
str2 = '01'
str3 = '0'
str4 = '3456789azAZ%'
run(pattern2,str1) #  
run(pattern2,str2) #  None
run(pattern2,str3) #  None
run(pattern2,str4) #  

3.2.2 数量修饰

修饰前面那个原子的数量

数量修饰
+ : 表示1个以上的数量, 例如 \d+ 表示1个以上的数字
? :表示0个 或 1个原子。 例如 \d?
* :表示任意数量的原子,包括0
{m} :表示 m个 原子
{m,n}: 表示 m到n个原子, 包含 m和n。 例如 \d{2,5} ,表示 2个到5个数字
{m , }  : 表示m个以上的原子
{ , n} :表示 n个以下的原子

 代码示例:

import re

# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)


##  数量修饰 ,
# 1.1 +, 标识 一个以上
pattern2 = 'a+'   # + 1个以上.
str ='aabc'
run(pattern2,str) #  


pattern2 = 'a+'   # + 1个以上.
str ='abc'
run(pattern2,str) #  


pattern2 = 'ab+'   # + 1个以上. 修饰的是之前那个 元字符, 这里就是 b。  所以结果不是 aaabb, 而是 abb
str ='aaabbc'
run(pattern2,str) #  


# 1.2: * , 标识 任意数量, 包括0

pattern2 = 'a*'   # * 任意数量
str ='aaabbc'
run(pattern2,str) #  


pattern2 = 'a*'   # * 任意数量 , 所以返回的是 match对象,以及其他信息。 而不是none
str ='bbc'
run(pattern2,str) #  


# 1.3: {m,n} , 指定数量, 左右的值都包括,即 m,n都包括

pattern2 = 'a{2,4}'   #  a的数量是 2-4 个, str有两个 所以符合。
str ='aabbc'
run(pattern2,str) #  


pattern2 = 'a{2,4}'   # a的数量是 2-4 个 , 只有一个所以不符合
str ='abbc'
run(pattern2,str) #  None


pattern2 = 'a{2,}'   # a的数量是 2 - 无穷大
str ='aaaaaaaaabbc'
run(pattern2,str) #  


pattern2 = 'a{,2}'   # a的数量是 0 - 2个 , 所以返回 match对象,而不是 none
str ='bbc'
run(pattern2,str) #  

3.2.3 位置修饰符

位置元字符
\A , ^ : 开头位置/起始位置  
\Z,, $   :结尾位置/以xxx结尾  
$^ 和 /Z/A的区别是, $^ 可以匹配多行的字符串。 /Z /A 只能匹配一行字符串。即使有多行的字符串,它也只匹配第一行。
^若在 [] 里面 [^] , 则表示非的意思。 例如[^1,2,3] , 非1,2,3。处理1,2,3以外的任意 原子。

代码示例:

import re

# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)

# 2. 位置修饰符。
# 开头位置/起始位置  \A , ^ , 必须放在最前面

pattern2 = '^a{,2}'   # 以a的数量是 0 - 2个开头
str ='aabbc'
run(pattern2,str) #  

pattern2 = '\Aa{,2}'   # 以a的数量是 0 - 2个开头
str ='aabbc'
run(pattern2,str) #  

pattern2 = 'a^'   #  ^ 这个必须放在最前面
str ='aabbc'
run(pattern2,str) #  None

pattern2 = 'a\A'   #   这个必须放在最前面
str ='aabbc'
run(pattern2,str) #  None


# 结尾位置/以xxx结尾  \Z, $  
# \Z,$ 必须放在最后面

pattern2 = 'a$'   # 以a结尾。 即 最后位置的值必须是a
str ='aabbc'
run(pattern2,str) #  None

pattern2 = 'a$'   # 以a结尾。 即 最后位置的值必须是a
str ='aabbca'
run(pattern2,str) #  

pattern2 = '$a'   # $,\Z 必须放在结尾位置, 所以这里结果是none
str ='aabbca'
run(pattern2,str) #  None

pattern2 = '\Za'   # $,\Z 必须放在结尾位置, 所以这里结果是none
str ='aabbca'
run(pattern2,str) #  None

pattern2 = 'a\Z'   # $,\Z 必须放在结尾位置
str ='aabbca'
run(pattern2,str) #  


## \A ^ 和 \Z $ 之间的区别是, ^和$ 可以用于多行
pattern2 = '^a'    # ^ 可以适应 多行匹配。 即第二行有 a开头的字符串, 也能匹配到
str ='''
=-34
abc
124
'''
res = re.search(pattern2,str,re.M)
print(type(res), res) #  


pattern2 = '\Aa'    # \A 只匹配第一行,即使在多行的 re.M 修正下 。 即第二行有 a开头的字符串, 也匹配不到,返回none  
str ='''
=-34
abc
124
'''
res = re.search(pattern2,str,re.M)
print(type(res), res) #  None

3.2.4 特殊修饰符

3.2.4.1 转义修饰符

\ :因为正则表达式有很多 特殊字符 \ , * & ^ 等, 有时候字符串需要 表示他们本身的含义,而不是 转义后的意思。

import re  # 导入 re模块

#### 正则表达式的应用测试步骤
# 1. 定义 正则表达式
# 2. 定义 检查字符
# 3. 检查


# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)

########
## 转义修饰
# 因为正则表达式有很多 特殊字符 \ , * & ^ 等, 有时候字符串需要 表示他们本身的含义,而不是 转义后的意思。
# 这时候只要在他们前面价格 转义字符 \ , 就是可以实现。  \. , \*
pattern1 = 'a*'  # 表示 匹配任意数量的a
pattern2 = 'a\*'  # 表示 要匹配 a*
str1 = 'aaaabcd'
run(pattern1, str1)  #  
run(pattern2, str1)  #  None

pattern1 = 'a.'  # 表示 a和任意字符
pattern2 = 'a\.'  # 表示 要匹配 a.
str1 = 'aaaabcd'
run(pattern1, str1)  #  
run(pattern2, str1)  #  None

3.2.4.2 词边界
词边界
\b : 表示能够当做 英文单词分隔的符号,即除了字母和数字以外的字符。 在字符串的开头需要 加转义: \\b
\B :表示字母和 数字
import re  # 导入 re模块

#### 正则表达式的应用测试步骤
# 1. 定义 正则表达式
# 2. 定义 检查字符
# 3. 检查

# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)

########
## 词边界修饰
# \b 需要 加转义\ , \\b
str1 = 'this is my house'
str2 = 'this ismy house'
str3 = 'this is$my house'

pattern2 = '\Bmy'
run(pattern2,str1) #  None
run(pattern2,str2) #  
run(pattern2,str3) #  None

pattern2 = '\\Bmy'
run(pattern2,str1) #  None
run(pattern2,str2) #  
run(pattern2,str3) #  None

pattern2 = '\bmy'
run(pattern2,str1) #  None
run(pattern2,str2) #  None
run(pattern2,str3) #  None

pattern2 = '\\bmy'  # 需要转义 \ s是的 \b 生效。 不知道为啥\b 必须要加 \ 转义。
run(pattern2,str1) #  
run(pattern2,str2) #  None
run(pattern2,str3) #  
 3.2.4.3  修饰关系

| : 表示选择关系 。  例如 ab|cd 。 表示 ab 或 cd。 从左向右 满足其中一个即可

3.2.4.4 ()

1. 表示将多个原子当做一个原子: 通常叫做模式单元或者组

2. 改变表达式的优先级: 例如 ab|cd ,  | 是最后执行的

a(b|c)d, 表示 abd或 acd, 在() 修饰后, | 是先执行的。

import re  # 导入 re模块

#### 正则表达式的应用测试步骤
# 1. 定义 正则表达式
# 2. 定义 检查字符
# 3. 检查

# 定义表达式的调用 函数
# 方便后续的测试
def run(pattern:str,str1:str):
    res = re.search(pattern,str1)
    print(type(res), res)

########
## 1. 将多个原子当做一个原子, 称为 模式单元或者 组
pattern2 = 'a|(cs)|cd'  # a 或 cs 或 cd
str1 = 'abc'    # 满足 a
str2 = 'bcs11'  # 满足 cs
str3 = 'bcwc'
run(pattern2,str1) #  
run(pattern2,str2) #  
run(pattern2,str3) #  None

## 2. 改变优先级
pattern2 = 'a(b|c)d'  # abd, acd . 若不加() ab|cd, 则是 ab,cd 在 | 。 加了括号改变了优先级, a (b|c) d 一起执行, 也就是 执行了 b|c
str1 = 'abc'    # 满足 a
str2 = 'abd'  # 满足 cs
str3 = 'acd'
run(pattern2,str1) #  None
run(pattern2,str2) #  
run(pattern2,str3) #  

## 3. 将匹配的内存存储到正则对象
## 涉及到后续的 扩展语法 (?:) , 取消单元存储到 对象.  默认存储到对象




3.3、模式修正符

设定额外的规则

模式修正符
re.A,  修正正则模式在 ASCII 编码的环境下
re.U,  修正正则模式在 UNICODE 编码的环境下,python3的默认编码。可以识别汉字
re.S , 修正模式中 . 的含义 。 使得 . 可以包含 \n
re.M , 修正表达式是否使用多行模式。 即能否匹配多行的字符串。通常和 ^ $搭配使用
re.X , 修正表达式使得匹配时,忽视表达式中的空格和注释内容
re.I , ignorecase, 修正表达式,忽视 表达式中的大小写。
import re  # 导入 re模块

#### 正则表达式的应用测试步骤
# 1. 定义 正则表达式
# 2. 定义 检查字符
# 3. 检查


######## 模式修正符 : 在正则表达式的基础上,设定额外的 规则
## 编码修正 re.A re.U
# re.A 使用 ascii 编码 , re.U 使用unicode编码。
# python3 默认使用 UNICODE编码,可以识别 汉字
pattern1 = r'\w'
str1 = '我is谁,who am 我'
res1 = re.findall(pattern1,str1,re.A)
res2 = re.findall(pattern1,str1,re.U) # unicode 可以识别汉字
print(type(res1),res1) #  ['i', 's', 'w', 'h', 'o', 'a', 'm']
print(type(res2),res2) #  ['我', 'i', 's', '谁', 'w', 'h', 'o', 'a', 'm', '我']

## re.S , 修正 .  。  是的 . 包含 \n
pattern1 = r'.'
str1 = '我\n是谁'
res1 = re.findall(pattern1,str1)
res2 = re.findall(pattern1,str1,re.S)
print(type(res1),res1) #  ['我', '是', '谁']
print(type(res2),res2) #  ['我', '\n', '是', '谁']

## re.M , 修正模式为 多行模式。 Multi
pattern1 = r'^www'  # 以 www 开头的字符串
str1 = 'www.baidu.com\nwww.google.com\nwww.sougou.com'
res1 = re.findall(pattern1,str1)
res2 = re.findall(pattern1,str1,re.M)  # 开启多行模式, 匹配多个结果
print(type(res1),res1) #  ['www']
print(type(res2),res2) #  ['www', 'www', 'www']

## re.X , 修正模式为 匹配时忽略表达式的注释和空格。 verbose
pattern1 = r'www .'  # 表达式含空格
str1 = 'www.baidu.com\nwww.google.com\nwww.sougou.com'
res1 = re.findall(pattern1,str1)
res2 = re.findall(pattern1,str1,re.X)
print(type(res1),res1) #  []
print(type(res2),res2) #  ['www.', 'www.', 'www.']

## re.I, 修正模式为 不区分大小写, ignore
pattern1 = r'wWw'  # 表达式含空格
str1 = 'wWw.baidu.com,WWW.google.com,www.sougou.com'
res1 = re.findall(pattern1,str1)
res2 = re.findall(pattern1,str1,re.I) # 忽视大小写, 所有都能匹配到
print(type(res1),res1) #  ['wWw']
print(type(res2),res2) #  ['wWw', 'WWW', 'www']



 

你可能感兴趣的:(编程语言,数据库,python)