正则表达式(Regular Expression,简称 regex)是处理文本数据的重要工具,尤其在系统日志分析、数据提取、格式转换等场景中发挥着不可替代的作用。本文将以两个典型的系统命令 who
和 tasklist
为例,深入解析如何使用 Python 正则表达式从非标准格式的输出中提取结构化数据。
🧩 一、问题背景:解析 who
命令输出
在 POSIX 系统(如 Linux 或 macOS)中,who
命令用于显示当前登录系统的用户信息,其输出如下所示:
wesley console Jun 20 20:33
wesley pts/9 Jun 22 01:38 (192.168.0.6)
wesley pts/1 Jun 20 20:33 (:0.0)
我们希望提取以下字段:
- 登录用户名
- 终端类型(如
pts/9
) - 登录时间
- 登录来源(可选,如 IP 地址或本地显示)
❗挑战点
- 空格数量不一致(
\s
不稳定) - 每行数据中包含多个空格或制表符
- 行尾可能存在换行符或制表符干扰
✅解决方案:使用 re.split(r'\s\s+', line)
分割字段
python
import re
with open('whodata.txt', 'r') as f:
for line in f:
fields = re.split(r'\s\s+', line.rstrip())
print(fields)
🧠技巧说明:
r'\s\s+'
:匹配两个或更多空白符(包括空格、制表符等)line.rstrip()
:去除行尾的换行符\n
- 使用
with
上下文管理器确保文件正确关闭
🧩 二、深入解析:从 tasklist
提取 Windows 进程信息
在 Windows 系统中,tasklist
命令用于显示当前运行的进程信息,输出如下:
Image Name PID Session Name Session# Mem Usage
========================= ====== ================ ======== ============
System Idle Process 0 Console 0 28 K
System 4 Console 0 240 K
smss.exe 708 Console 0 420 K
我们希望提取:
- 进程名称(如
System Idle Process
) - PID(进程 ID)
- 内存使用(如
28 K
)
❗挑战点
- 进程名称中包含空格(如
System Idle Process
) - 列之间仅使用单个空格分隔(
PID Session Name
) - 内存使用格式不统一(如
4,876 K
)
✅解决方案:使用正则表达式匹配完整行结构
python
import re
import os
pattern = r'^(.+?)\s+(\d+)\s+\S+\s+\d+\s+(\d+,\d+ K|\d+ K)$'
with os.popen('tasklist /nh') as f:
for line in f:
match = re.match(pattern, line.strip())
if match:
print(match.groups())
🧠技巧说明:
- 使用
^
和$
匹配整行 - 使用非贪婪
.+?
匹配进程名 - 使用
\d+
匹配数字 - 处理内存格式的可选逗号(如
4,876 K
) - 使用
os.popen()
直接调用系统命令,避免手动保存文件
🎯 三、正则表达式的强大功能总结
正则表达式不仅限于简单匹配和分割,还可以实现:
功能 | 正则表达式示例 | 说明 |
---|---|---|
分割字段 | re.split(r'\s\s+', line) |
处理不一致的空白符 |
提取字段 | re.match(r'(\w+)\s+(\d+)', line) |
使用分组提取关键信息 |
忽略大小写 | re.IGNORECASE |
匹配不区分大小写的字段 |
多行匹配 | re.MULTILINE |
匹配多行文本中的每一行 |
非贪婪匹配 | .*? |
避免匹配过长的内容 |
💡 四、构建通用脚本:兼容 Python 2 与 Python 3
为了兼容 Python 2 和 3,可以使用以下技巧:
- 使用
from __future__ import with_statement
启用with
语句 - 使用
distutils.log.warn()
替代print()
(适用于 Python 2 和 3 的兼容输出) - 使用条件判断区分 Python 版本
python
import sys
if sys.version_info[0] < 3:
from distutils.log import warn as printf
else:
printf = print
🚀 五、应用场景拓展:从日志中提取结构化数据
正则表达式不仅适用于命令行输出解析,还可以广泛应用于:
- Web 日志分析(如访问日志、错误日志)
- 数据清洗与格式转换
- 网络爬虫提取特定字段
- 配置文件解析(如
.ini
、.conf
)
🧪 示例:从日志文件中提取 IP 地址
python
log_line = '192.168.0.1 - - [22/Feb/2023:14:30:00] "GET /index.html HTTP/1.1" 200 1024'
ip = re.search(r'(\d+\.\d+\.\d+\.\d+)', log_line)
if ip:
print("IP Address:", ip.group())
📌 六、结语:正则是文本处理的基石
正则表达式是每一位 Python 开发者必须掌握的核心技能之一。它不仅帮助我们从非结构化数据中提取有用信息,还提升了脚本的自动化与智能化水平。
通过本文的 who
和 tasklist
示例,我们掌握了:
- 如何使用正则表达式处理不规则的空白符
- 如何构建可复用、可扩展的脚本
- 如何在不同操作系统和 Python 版本之间保持兼容性
- 如何将正则应用于更广泛的文本处理场景
掌握这些技能,将使你在系统管理、数据分析、自动化运维等领域如虎添翼。