感谢点赞和关注 ,每天进步一点点!加油!
目录
一、Python 正则表达式
1.1 re模块常用操作
1.2 re.match
1.3 re.search
1.4 re.findall
1.5 re.compile 函数
1.6 re.sub 检索和替换
1.7 re.split拆分
1.8 实战案例:根据文件名匹配文件并移动
Python 系列文章学习记录:
Python系列之Windows环境安装配置_开着拖拉机回家的博客-CSDN博客
Python系列之变量和运算符_开着拖拉机回家的博客-CSDN博客
Python系列之判断和循环_开着拖拉机回家的博客-CSDN博客
Python系列之字符串和列表_开着拖拉机回家的博客-CSDN博客
Python系列之文件操作和函数_开着拖拉机回家的博客-CSDN博客
Python系列模块之标准库OS详解_开着拖拉机回家的博客-CSDN博客
Python系列模块之标准库re详解_开着拖拉机回家的博客-CSDN博客
Python系列模块之标准库json详解_开着拖拉机回家的博客-CSDN博客
Python系列模块之标准库shutil详解_开着拖拉机回家的博客-CSDN博客
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
模块+函数(方法) |
描述 |
re.match() |
开头匹配,类似shell里的^符号 |
re.search() |
整行匹配,但只匹配第一个 |
re.findall() |
全匹配并把所有匹配的字符串做成列表 |
re.split() |
以匹配的字符串做分隔符,并将分隔的转为list类型 |
re.sub() |
匹配并替换 |
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none。
函数语法:
re.match(pattern, string, flags=0)
函数参数说明:
参数 |
描述 |
pattern |
匹配的正则表达式 |
string |
要匹配的字符串。 |
flags |
标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 |
匹配成功 re.match 方法返回一个匹配的对象,否则返回 None。
我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 |
描述 |
group(num=0) |
匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() |
返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
实例:
import re
print(re.match("aaa", "sdfaaasd")) # 结果为none,表示匹配未成功
print(re.match("aaa", "aaasd")) # 有结果输出,表示匹配成功
abc = re.match("aaa\d+", "aaa234324bbbbccc")
print(abc.group()) # 结果为aaa234324,表示打印出匹配那部分字符串
执行结果:
re.search 扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
函数参数说明:
参数 |
描述 |
pattern |
匹配的正则表达式 |
string |
要匹配的字符串。 |
flags |
标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
匹配成功re.search方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 |
描述 |
group(num=0) |
匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() |
返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
实例:
import re
# 有结果输出,表示匹配成功;re.search就是全匹配,而不是开头(但只返回一个匹配的结果);想开头匹配的话可以使用^aaa
print(re.search("hadoop", "sdfhadoopsdhadoopwwsdf"))
# 验证,确实只返回一个匹配的结果,并使用group方法将其匹配结果打印出来
print(re.search("hadoop\d+", "hadoop111222bbbbccchadoop333444").group())
执行结果:
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次 ,findall 匹配所有。
语法格式为:
findall(string[, pos[, endpos]])
函数参数说明:
参数 |
描述 |
string |
待匹配的字符串。 |
pos |
可选参数,指定字符串的起始位置,默认为 0。 |
endpos |
可选参数,指定字符串的结束位置,默认为字符串的长度。 |
实例:
import re
print(re.findall("hadoop", "sdfhadoopsdhadoopwwsdf"))
print(re.findall("hadoop\d+", "hadoop111222bbbbccchadoop333444"))
执行结果:
小结: re.search()与re.findall()
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
语法格式为:
re.compile(pattern[, flags])
测试数据
t1.4301.jyg.qcs.ipva.cn,0,1,1,PsARegion,4#37#6#85#272#70#268#17
t1.4301.jyg.qcs.ipva.cn,0,1,1,PsCRegion,275#94#9#105#13#147#285#140
t1.py.3895.qcs.ipva.cn,0,1,1,PsDRegion,84#86#228#88#216#138#98#139
t1.py.3895.qcs.ipva.cn,1,1,1,PsARegion,77#85#239#87#218#133#99#132
t1.8381.kf.qcs.ipva.cn,0,1,1,PsBRegion,125#145#320#146#330#207#67#210
t1.8381.kf.qcs.ipva.cn,0,1,1,PsCRegion,126#143#322#146#329#208#68#210
需求:匹配到"PsARegion"的行输出
import re
f = open("/root/data.txt") # 返回一个文件对象
line = f.readline() # 调用文件的 readline()方法
text = ""
pattern = re.compile("PsARegion")
while line:
if(pattern.search(line)):
# 拼接
text += line
line = f.readline()
print(text, end='')
f.close()
执行结果:正确的匹配输出了两行数据
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
函数参数说明:
参数 |
描述 |
pattern |
正则中的模式字符串。 |
pos |
替换的字符串,也可为一个函数。 |
string |
要被查找替换的原始字符串。 |
count |
模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。 |
实例:
import re
phone = "2004-959-559 # 这是一个国外电话号码"
# 删除字符串中的 Python注释
num = re.sub(r'#.*$', "", phone)
print("电话号码是: ", num)
# 删除非数字(-)的字符串
num = re.sub(r'\D', "", phone)
print("电话号码是: ", num)
执行结果:
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
参数:
参数 |
描述 |
pattern |
匹配的正则表达式 |
string |
要匹配的字符串。 |
maxsplit |
分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。 |
flags |
标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 |
测试数据:
t1.4301.jyg.qcs.ipva.cn,0,1,1,PsARegion,4#37#6#85#272#70#268#17
t1.4301.jyg.qcs.ipva.cn,0,1,1,PsCRegion,275#94#9#105#13#147#285#140
t1.py.3895.qcs.ipva.cn,0,1,1,PsDRegion,84#86#228#88#216#138#98#139
t1.py.3895.qcs.ipva.cn,1,1,1,PsARegion,77#85#239#87#218#133#99#132
t1.8381.kf.qcs.ipva.cn,0,1,1,PsBRegion,125#145#320#146#330#207#67#210
t1.8381.kf.qcs.ipva.cn,0,1,1,PsCRegion,126#143#322#146#329#208#68#21
需求:正则匹配 “PsARegion” 的行且取出前两个列
import re
f = open("/root/data.txt") # 返回一个文件对象
line = f.readline() # 调用文件的 readline()方法
text = ""
pattern = re.compile("PsARegion")
while line:
if(pattern.search(line)):
dataList = re.split(",", line)
line = str(dataList[0]) + "," + str(dataList[1]) + "\n"
text += line
line = f.readline()
print(text, end='')
f.close()
执行结果:
move_file.py
# -*- coding:UTF-8 -*-
import logging
import os
import re
import shutil
import sys
from imp import reload
from logging.handlers import RotatingFileHandler
reload(sys)
# 初始化日志
logger = logging.getLogger('mylogger')
logger.setLevel(level=logging.INFO)
fmt = '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
format_str = logging.Formatter(fmt)
fh = RotatingFileHandler("move_file.log", maxBytes=10*1024*1024, backupCount=2,encoding="utf-8")
fh.namer = lambda x: "backup."+x.split(".")[-1]
fh.setFormatter(fmt=format_str)
logger.addHandler(fh)
def move_file(res_dir, tar_dir, pattern):
""" 文件移动
:param res_dir: 源路径
:param tar_dir: 目标路径
:param pattern: 正则匹配模式
:return:
"""
try:
logger.info("开始移动文件!")
for filename in os.listdir(res_dir):
# 获取文件的完整路径
file_path = os.path.join(res_dir, filename)
print(filename, pattern)
# 正则匹配文件名
if re.match(pattern, filename):
shutil.move(file_path, tar_dir) # 移动文件 # shutil库,它作为os模块的补充,提供了复制、移动、删除、压缩、解压
print("已移动文件【%s】" %filename)
logger.info("结束移动文件!")
except Exception as why:
print(why)
if __name__ == "__main__":
print(sys.argv)
if len(sys.argv) == 4:
move_file(sys.argv[1], sys.argv[2], sys.argv[3])
在Windows 上调用
python.exe D:\\IPVA\\file_move\\move_file.py D:\\IPVA\Data_Traffic\\DataServerCloud01_AlarmEvent\\ D:\\IPVA\Data_Traffic_Bak\\DataServerCloud01_AlarmEvent\\ Data.*.COMPLETED
移动成功, 之后我又做了ren重命名
参考:
Python 正则表达式 | 菜鸟教程
Python四种逐行读取文件内容的方法 - 简书