正则表达式
1.原子
2.元字符
3.模式修正
4.贪婪模式
5.懒惰模式
1.原子
原子是正则表达式中最基本的组成单位,每个正则表达式中至少要包含一个原子,
常见的原子有一下几类:
普通字符作为原子
非打印字符作为原子
通用字符作为原子
原子表
普通字符作为原子
一些普通字符,例如:字母,数字,下划线都可以作为原子.
import re
pattern = "test" # 普通字符作为原子
string = "asdfatestsdfasd"
result1 = re.search(pattern, string)
print(result1)
<_sre.SRE_Match object; span=(5, 9), match='test'>
- 非打印字符作为原子
非打印字符就像换行符之类的符号.
import re
pattern = '\n'
string = '''http://baidu.com
test'''
result1 = re.search(pattern, string)
print(result1)
<_sre.SRE_Match object; span=(16, 17), match='\n'>
#!/usr/bin/env python3
import re
pattern = '\n'
string = '''http://baidu.com
test
test'''
result1 = re.search(pattern, string)
print(result1)
<_sre.SRE_Match object; span=(16, 17), match='\n'>
但是即使有多个换行符也只能匹配到一个.
- 通用字符作为原子
通用字符可以匹配一类字符,经常用到.
符号 | 含义 |
---|---|
\w | 匹配任意一个字母,数字或下划线 |
\W | 匹配除字母,数字或下划线以外的任意一个字符 |
\d | 匹配任意一个十进制数 |
\D | 匹配除十进制数外的任意一个 其他字符 |
\s | 匹配任意一个空白字符 |
\S | 匹配除空白字符以外的任意一个字符 |
#!/usr/bin/env python3
import re
string1 = 'asdfas234234234python234234_py'
string2 = 'asdfas234234234\npython234234_py'
pattern1 = '\w\dpython'
pattern2 = '\Wpython'
pattern3 = '\dpython'
pattern4 = '\Dpython'
pattern5 = '\s'
pattern6 = '\S'
result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string2)
result3 = re.search(pattern3, string1)
result4 = re.search(pattern4, string1)
result5 = re.search(pattern5, string2)
result6 = re.search(pattern6, string2)
print(result1)
print(result2)
print(result3)
print(result4)
print(result5)
print(result6)
<_sre.SRE_Match object; span=(13, 21), match='34python'>
<_sre.SRE_Match object; span=(15, 22), match='\npython'>
<_sre.SRE_Match object; span=(14, 21), match='4python'>
None
<_sre.SRE_Match object; span=(15, 16), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match='a'>
- 原子表
使用原子表,可以定义一组地位平等的原子,然后匹配时会去该原子表中的任意一个原子
进行匹配,在python中,原子表由[]表示,例如[xyz]就是一个原子表,在这个原子表中定义
了3个原子,这3个原子的地位平等,如
#!/usr/bin/env python3
import re
string1 = 'asdfas234234234python234234_py'
pattern1 = '[1234]python'
pattern2 = '[opq]ython'
result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string1)
print(result1)
print(result2)
类似的,[^]代表的是除了中括号里面的原子均可以匹配,比如
#!/usr/bin/env python3
import re
string1 = 'asdfas234234234pythony234234_py'
pattern1 = '\w\dpython[xyz]\w'
pattern2 = '\w\dpython[^xz]\w'
pattern3 = '\w\dpython[xyz]\W'
result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string1)
result3 = re.search(pattern3, string1)
print(result1)
print(result2)
print(result3)
<_sre.SRE_Match object; span=(13, 23), match='34pythony2'>
<_sre.SRE_Match object; span=(13, 23), match='34pythony2'>
None
2.元字符
元字符就是正则表达式中含有一些特殊意义的字符,比如重复N次前面的字符
元字符可以分成五类:
- 任意匹配元字符 如:"."
- 边界限制元字符 如:"^"和"$"
- 限定符 如:"*","?","+","{n}","{n,}","{n,m}"
- 模式选择符 如:"|"
- 模式单元符 如:"()"
常见的元字符及含义
符号 | 含义 |
---|---|
. | 匹配除换行符以外的任意字符 |
^ | 匹配字符串的开始位置 |
$ | 匹配字符串的结束位置 |
* | 匹配0次,1次或多次前面的原子 |
? | 匹配0次或1次前面的原子 |
+ | 匹配1次或多次前面的原子 |
{n} | 前面的原子恰好出现n次 |
{n,} | 前面的原子至少出现n次 |
{n,m} | 前面的原子至少出现n次,最多出现m次 |
| | 模式选择符,匹配时可以任意选择一个模式匹配 |
() | 模式单元符,将一些原组合成一个大原子使用 |
一些使用例子:
#!/usr/bin/env python3
import re
pattern = '.python...'
string = 'bacdefphp345python_py'
result = re.search(pattern, string)
print(result)
<_sre.SRE_Match object; span=(11, 21), match='5python_py'>
-------------------------------------------------------------
#!/usr/bin/env python3
import re
pattern1 = '^abd' # 从字符串的开始去找abd
pattern2 = '^abc' # 从字符串的开始去找abc
pattern3 = 'py$' # 从字符串的结尾去找py
pattern4 = 'ay$' # 从字符串的尾部去找ay
string = 'abcdfphp345python_py'
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
None
<_sre.SRE_Match object; span=(0, 3), match='abc'>
<_sre.SRE_Match object; span=(18, 20), match='py'>
None
-------------------------------------------------------------
#!/usr/bin/env python3
import re
pattern1 = 'py.*n'
pattern2 = 'cd{2}'
pattern3 = 'cd{3}'
pattern4 = 'cd{2,}'
string = 'abcdddfphp345pythony_py'
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
result3 = re.search(pattern3, string)
result4 = re.search(pattern4, string)
print(result1)
print(result2)
print(result3)
print(result4)
<_sre.SRE_Match object; span=(13, 19), match='python'>
<_sre.SRE_Match object; span=(2, 5), match='cdd'>
<_sre.SRE_Match object; span=(2, 6), match='cddd'>
<_sre.SRE_Match object; span=(2, 6), match='cddd'>
-------------------------------------------------------------
#!/usr/bin/env python3
import re
pattern1 = 'python|php'
string = 'abcdddfphp345pythony_py'
result1 = re.search(pattern1, string)
print(result1)
<_sre.SRE_Match object; span=(7, 10), match='php'>
-------------------------------------------------------------
#!/usr/bin/env python3
import re
pattern1 = '(cd){1,}'
pattern2 = 'cd{1,}'
string = 'abcdcdcddfphp345pythony_py'
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1)
print(result2)
<_sre.SRE_Match object; span=(2, 8), match='cdcdcd'>
<_sre.SRE_Match object; span=(2, 4), match='cd'>
-------------------------------------------------------------
符号 | 含义 |
---|---|
I | 匹配时忽略大小写 |
M | 多行匹配 |
L | 做本地化识别匹配 |
U | 根据Unicode字符及解析字符 |
S | 让.匹配包含换行符,即用修正模式,"."可以匹配任意字符 |
3.模式修正
模式修正符:可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,
从而实现一些匹配结果的调整等功能.
常见模式修正符
符号 | 含义 |
---|---|
I | 匹配时忽略大小写 |
M | 多行匹配 |
L | 做本地化识别匹配 |
U | 根据Unicode字符及解析字符 |
S | 让.匹配包含换行符,即用修正模式,"."可以匹配任意字符 |
#!/usr/bin/env python3
import re
pattern1 = 'python'
pattern2 = 'python'
pattern3 = 'Pythony.'
string = 'abcdfphp345Pythony_py'
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string, re.I)
result3 = re.search(pattern3, string, re.S)
print(result1)
print(result2)
print(result3)
None
<_sre.SRE_Match object; span=(11, 17), match='Python'>
<_sre.SRE_Match object; span=(11, 19), match='Pythony_'>
4.贪婪模式与懒惰模式
贪婪模式就是尽可能多的匹配
懒惰模式就是尽可能少的匹配
#!/usr/bin/env python3
import re
pattern1 = 'p.*y'
pattern2 = 'p.*?y'
string = 'abcdfphp345Pythony_py'
result1 = re.search(pattern1, string)
result2 = re.search(pattern2, string)
print(result1)
print(result2)
<_sre.SRE_Match object; span=(5, 21), match='php345Pythony_py'>
<_sre.SRE_Match object; span=(5, 13), match='php345Py'>
正则表达式常见函数:re.match(), re.search(), 全局匹配函数, re.sub()
- re.match()
从源字符串的起始位置匹配一个模式,我们可以使用re.match()
re.match(pattern, string, flag)
pattern:对应的表达式
string: 源字符串
flag: 可选,对应的标志位,可放模式修正符
import re
string = 'apythonhellomypythonhispythonourpythonend'
pattern = '.python'
result = re.match(pattern, string)
result2 = re.match(pattern, string).span()
print(result)
print(result2)
<_sre.SRE_Match object; span=(0, 7), match='apython'>
(0, 7)
- re.search()
使用该函数进行匹配,会扫描整个字符串进行对应的匹配. re.match()从源字符串的
开头进行匹配,而re.search()会在全文进行检索并匹配.
import re
string = 'hellomypythonhispythonourpythonend'
pattern = '.python.'
result = re.match(pattern, string)
result2 = re.search(pattern, string)
print(result)
print(result2)
None
<_sre.SRE_Match object; span=(6, 14), match='ypythonh'>
re.mathc()从头开始匹配,而开头不符合正则表达式,所以返回None
- 全局匹配函数
前面两个函数即使源字符串中多个结果符合模式,也只会返回一个结果.
怎么把所有的内容全部匹配出来?
思路如下:- 使用re.compile()对正则表达式进行编译
- 编译后,使用findall()根据正则表达式从源字符串中将匹配结果全部找出
import re
string = 'hellomypythonhispythonourpythonend'
pattern = re.compile('.python.') # 预编译
result = pattern.findall(string) # 找出符合模式的所有结果
print(result)
['ypythonh', 'spythono', 'rpythone']
也可以将两步合并到一步
import re
string = 'hellomypythonhispythonourpythonend'
result = re.compile('.python.').findall(string) # 找出符合模式的所有结果
print(result)
['ypythonh', 'spythono', 'rpythone']
- re.sub()
用来实现字符串替换功能
re.sub(pattern, rep, string, max)
pattern: 正则表达式
rep: 为要替换成的字符串
string: 源字符串
max: 为可选项,代表最多替换的次数,如果忽略不写,则会将符合模式的结果全部替换
import re
string = 'hellomypythonhispythonourpythonend'
pattern = 'python.'
result = re.sub(pattern, 'php', string) # 全部替换
result2 = re.sub(pattern, 'php', string, 2) # 最多替换2次
print(result)
print(result2)
hellomyphpisphpurphpnd
hellomyphpisphpurpythonend