Python学习之------正则表达式
参考
简单使用:python re.match函数的使用
Python通过re模块提供对正则表达式的支持,常用的正则表达式函数有re.match(),re.search(),re,findall()
常见用法
re.match
python
re.match(pattern, string, flags=0)
"""
从字符串string的开始位置开始匹配模式pattern,如果不是开始位置匹配成功的话,返回none
Args:
pattern: 匹配的正则表达式
string: 待匹配的字符串
flags:可选标志位,表示匹配模式,常见标志位有:
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和 # 后面的注释
Return:
开始位置匹配成功, 返回一个匹配对象re.Match object
不是开始位置匹配成功的话,返回None
"""
示例
python
import re
def test_re_match():
print('============I am test_re_match============')
pattern = r'([0-9.-]+)([%]?)([0-9.]*)'
test_str = '45.1%23s'
match_obj = re.match(pattern, test_str)
match_obj_group = match_obj.group()
match_obj_group0 = match_obj.group(0)
match_obj_group1 = match_obj.group(1)
match_obj_group2 = match_obj.group(2)
match_obj_group3 = match_obj.group(3)
match_obj_span = match_obj.span()
print(f'\
match_obj_group:{match_obj_group}\n\
match_obj_group0:{match_obj_group0}\n\
match_obj_group1:{match_obj_group1}\n\
match_obj_group2:{match_obj_group2}\n\
match_obj_group3:{match_obj_group3}\n\
match_obj_span:{match_obj_span}\n\
===========================================')
if __name__ == '__main__':
test_re_match()
""" 结果
============I am test_re_match============
match_obj_group:45.1%23
match_obj_group0:45.1%23
match_obj_group1:45.1
match_obj_group2:%
match_obj_group3:23
match_obj_span:(0, 7)
===========================================
"""
re.search
search()和match()的区别:搜索的起始位置不同
search(): 从整个字符串中搜索第一个匹配的子串,不限制搜索的起始位置。
match(): 从字符串的开头开始匹配,只在字符串开头找到匹配的子串
python
re.search(pattern, string, flags=0)
"""
扫描整个字符串并返回第一个成功的匹配。
Args:
pattern: 匹配的正则表达式
string: 待匹配的字符串
flags:可选标志位,表示匹配模式,常见标志位有:
Return:
搜索成功,返回第一个成功的匹配对象re.Match object
搜索失败,返回None
"""
示例
python
import re
def test_re_search():
print('============I am test_re_search============')
pattern = r'([0-9.-]+)([%]?)([0-9.]*)'
test_str = 'abc45.1%23sdef'
match_obj = re.search(pattern, test_str)
match_obj_group = match_obj.group()
match_obj_group0 = match_obj.group(0)
match_obj_group1 = match_obj.group(1)
match_obj_group2 = match_obj.group(2)
match_obj_group3 = match_obj.group(3)
match_obj_span = match_obj.span()
print(f'\
match_obj_group:{match_obj_group}\n\
match_obj_group0:{match_obj_group0}\n\
match_obj_group1:{match_obj_group1}\n\
match_obj_group2:{match_obj_group2}\n\
match_obj_group3:{match_obj_group3}\n\
match_obj_span:{match_obj_span}\n\
===========================================')
if __name__ == '__main__':
test_re_search()
""" 结果
============I am test_re_search============
match_obj_group:45.1%23
match_obj_group0:45.1%23
match_obj_group1:45.1
match_obj_group2:%
match_obj_group3:23
match_obj_span:(3, 10)
===========================================
"""
分组
在匹配的正则表达式pattern中用小括号()括起来就是一个捕获组, 对于匹配成功后返回的象匹配对象re.Match object,我们可以调用匹配对象re.Match object的group()函数来提取每组匹配到的字符串。
python
group():返回一个包含所有小组字符串的元组。
group(0):和group()一样,返回一个包含所有小组字符串的元组。
group(1):返回第一个小括号()括起来的捕获组的字符串。
group(2):返回第二个小括号()括起来的捕获组的字符串。
以此类推....
示例
python
import re
def test_re_group():
print('============I am test_re_group============')
pattern = r'([0-9.-]+)([\+\-\*\/]+)([0-9.-]+)'
test_str = 'abc12.2*51.9def'
match_obj = re.search(pattern, test_str)
match_obj_group = match_obj.group()
match_obj_group0 = match_obj.group(0)
match_obj_group1 = match_obj.group(1)
match_obj_group2 = match_obj.group(2)
match_obj_group3 = match_obj.group(3)
match_obj_span = match_obj.span()
print(f'\
match_obj_group:{match_obj_group}\n\
match_obj_group0:{match_obj_group0}\n\
match_obj_group1:{match_obj_group1}\n\
match_obj_group2:{match_obj_group2}\n\
match_obj_group3:{match_obj_group3}\n\
match_obj_span:{match_obj_span}\n\
===========================================')
if __name__ == '__main__':
test_re_group()
""" 结果
============I am test_re_group============
match_obj_group:12.2*51.9
match_obj_group0:12.2*51.9
match_obj_group1:12.2
match_obj_group2:*
match_obj_group3:51.9
match_obj_span:(3, 12)
===========================================
"""
re.sub
python
re.sub(pattern, repl, string, count=0, flags=0)
"""
用于替换字符串中的匹配项
Args:
pattern: 匹配的正则表达式
repl : 替换的字符串,也可为一个函数。
string: 待匹配的字符串
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags:可选标志位,表示匹配模式
"""
示例
使用正则表达式来实现将大驼峰命名的字符串转成蛇形命名
python
import re
def camel_to_snake(camel_str: str):
"""大驼峰转蛇形"""
snake_str = re.sub(r"(?P<key>[A-Z])", r"_\g<key>", camel_str)
return snake_str.lower().lstrip('_')
def test_re_sub():
print('============I am test_re_sub============')
temp = 'TestName'
after_temp = camel_to_snake(temp)
print(f'temp:{temp}, camel_to_snake(temp): {after_temp}')
print('===========================================')
if __name__ == '__main__':
test_re_sub()
"""结果
============I am test_re_sub============
temp:TestName, camel_to_snake(temp): test_name
===========================================
"""
re.findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
python
re.findall(pattern, string, flags=0)
"""
用于搜索字符串string中和正则表达式pattern匹配的所有匹配项
Args:
pattern: 匹配的正则表达式
string: 待匹配的字符串
flags:可选标志位,表示匹配模式
"""
示例
python
import re
def test_re_findall():
print('============I am test_re_findall============')
test_str = 'abc123 def 456ghi78'
pattern1 = r'\d+'
result_list1 = re.findall(pattern1, test_str)
print(f'result_list1:{result_list1}')
# findall中含有分组时
pattern2 = r'([a-zA-Z]+)(\d+)'
result_list2 = re.findall(pattern2, test_str)
print(f'result_list2:{result_list2}')
print('===========================================')
if __name__ == '__main__':
test_re_findall()
""" 结果
============I am test_re_findall============
result_list1:['123', '456', '78']
result_list2:[('abc', '123'), ('ghi', '78')]
===========================================
"""
使用编译后的正则表达式
当我们需要多次使用相同的正则表达式时,可以先对正则表达式进行编译,以提高效率
示例:检查属性命名是否 满足 '字母或者下划线开头"
python
valid_name_regex = re.compile(r"^[_A-Za-z][_0-9A-Za-z]*$")
def check_name_valid(name):
"""
检查属性命名是否 满足 '字母或者下划线开头"
"""
if valid_name_regex.match(name) is None:
print(f'name:{name} is invalid!!!!!!!')
return False
else:
print(f'name:{name} is valid!!!!!!!')
return True
def test_re_compile():
print('============I am test_re_compile============')
property_names = ['name', '_age', '12', "a12"]
for property_name in property_names:
check_name_valid(property_name)
print('===========================================')
if __name__ == '__main__':
test_re_compile()
"""结果
============I am test_re_compile============
name:name is valid!!!!!!!
name:_age is valid!!!!!!!
name:12 is invalid!!!!!!!
name:a12 is valid!!!!!!!
===========================================
"""
实例
1.匹配中文字符串并替换
python
def test_replace_chinese_word():
test_str_list = ["12'你好'3'世界'", 'abc', 'c"真的吗"ab']
pattern1 = r'(\')(.*?)(\')'
pattern2 = r'(\")(.*?)(\")'
for index, test_str in enumerate(test_str_list):
ret = []
ret.extend(re.findall(pattern1, test_str))
ret.extend(re.findall(pattern2, test_str))
replace_test_str = test_str
for pre, content, post in ret:
if any(['\u4e00' <= char <= '\u9fff' for char in content]):
print(f'pre:{pre}, content:{content}, post:{post}')
replace_test_str = replace_test_str.replace(f'{pre}{content}{post}', f'ZH_CN({pre}{content}{post})')
test_str_list[index] = replace_test_str
print(f'test_str_list:{test_str_list}')
print('===========================================')
"""结果
===========================================
pre:', content:你好, post:'
pre:', content:世界, post:'
pre:", content:真的吗, post:"
test_str_list:["12ZH_CN('你好')3ZH_CN('世界')", 'abc', 'cZH_CN("真的吗")ab']
===========================================
"""