感谢点赞和关注 ,每天进步一点点!加油!
目录
一、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 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
- re 模块使 Python 语言拥有全部的正则表达式功能。
- compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
- re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
1.1 re模块常用操作
模块+函数(方法) | 描述 |
re.match() | 开头匹配,类似shell里的^符号 |
re.search() | 整行匹配,但只匹配第一个 |
re.findall() | 全匹配并把所有匹配的字符串做成列表 |
re.split() | 以匹配的字符串做分隔符,并将分隔的转为list类型 |
re.sub() | 匹配并替换 |
1.2 re.match
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,表示打印出匹配那部分字符串
执行结果:
1.3 re.search
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())
执行结果:
1.4 re.findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
注意: 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()
- re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
- 都不是开头匹配
- re.search()只匹配一行里第一个,而re.findall()会把一行内匹配的多个都匹配出来
- re.search()可以通过group()打印匹配的结果, re.findall()没有group()方法,直接把匹配的所有结果以列表的形式展示
1.5 re.compile 函数
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()
执行结果:正确的匹配输出了两行数据
1.6 re.sub 检索和替换
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)
执行结果:
1.7 re.split拆分
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()
执行结果:
1.8 实战案例:根据文件名匹配文件并移动
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四种逐行读取文件内容的方法 - 简书