Pyparsing

Sunmy Lv5

PyParsing学习

安装

1
pip install pyparsing

架构与组成

基本元素

  1. Literal: 匹配固定的字符串。
  2. Word: 匹配由特定字符组成的单词。
  3. Chars: 匹配一组字符中的任意一个。
  4. nums: 预定义的字符集,表示数字(0-9)。
  5. alphas: 预定义的字符集,表示字符(a-zA-Z)。
  6. alphanums: 预定义的字符集,表述字母和数字(a-zA-Z0-9)
  7. Combine: 将多个解析结果合并为一个字符串。
  8. Group:将多个解析结果分组。

测试脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# 导入 pyparsing 模块中的必要类
from pyparsing import (
Word, # 用于匹配单词或特定字符集合
nums, # 预定义的字符集,表示数字(0-9)
alphas, # 预定义的字符集,表示字母(a-zA-Z)
Literal, # 用于匹配固定的字符串
SkipTo, # 跳过所有内容,直到匹配到指定的模式
Optional, # 表示可选部分
Combine, # 用于连接多个模式
)


def analysis_logs(log_content):
"""
解析日志内容
:param log_content: 日志内容
:return: None
"""
# 定义语法规则
# 匹配测试用例的 ID(由数字组成)
template_test_case_id = Word(nums)

# 匹配测试用例的名称(由字母、数字和下划线组成)
template_test_case_name = Word(alphas + nums + "_")

# 匹配固定的字符串 "starting ...!"
template_starting = Literal("starting ...!")

# 匹配结果部分的分隔符("!!!" 或 "@@@")
template_result_sep = Literal("!!!") | Literal("@@@")

# 匹配结果标志(由字母组成,如 "PASS" 或 "FAIL")
template_result_flag = Word(alphas)

# 定义完整模式
pattern = (
Literal("Test Case") # 匹配固定的字符串 "Test Case"
+ template_test_case_id(
"case_exec_id"
) # 匹配测试用例的 ID,并将其命名为 case_exec_id
+ ":" # 匹配冒号
+ template_test_case_name(
"case_name"
) # 匹配测试用例的名称,并将其命名为 case_name
+ template_starting # 匹配固定的字符串 "starting ...!"
+ SkipTo(template_result_sep | "Test Case")(
"content"
) # 匹配内容,直到遇到分隔符或下一个测试用例
+ Optional( # 可选部分:匹配 RESULT 部分
template_result_sep("result_sep1")
+ Literal("RESULT: Test Case")
+ template_test_case_id("case_exec_res_id")
+ ":"
+ template_test_case_name("case_res_name")
+ template_result_flag("template_result_flag")
+ template_result_sep("result_sep2")
)
)

# 解析日志内容(匹配所有记录)
parsed_results = pattern.searchString(log_content)

# 输出解析结果
# 输出解析结果
for i, parsed_result in enumerate(parsed_results, 1):
print(f"Test Case {i}:")
print(f"\tTest Case ID: {parsed_result['case_exec_id']}")
print(f"\tTest Case Name: {parsed_result['case_name']}")

# 检查是否有 RESULT 部分
if "result_sep1" in parsed_result:
print(f"\tResult Separator 1: {parsed_result['result_sep1']}")
print(f"\tResult Separator 2: {parsed_result['result_sep2']}")
print(f"\tTest Result Flag: {parsed_result['template_result_flag']}")
else:
print("\tResult: Incomplete (No RESULT section found)")

# 检查 content 是否为空
content = parsed_result[
"content"
].strip() # 使用 strip() 去掉开头和结尾的空白字符
if content:
print(f"\tContent:\n{content}") # 输出去掉空行后的内容
else:
print("\tContent: 无")

print("=" * 40)


from pyparsing import Literal, Word, nums, Combine, StringEnd


def analysis_logs_login(log_content):
"""
解析日志内容,统计每天的登录次数
:param log_content: 日志内容
:return: 每天的登录次数(字典形式)
"""
# 定义语法规则
template_starting = Literal("use time: ") # 匹配固定的字符串 "use time: "
template_date = Combine(
Word(nums, exact=4) + "-" + Word(nums, exact=2) + "-" + Word(nums, exact=2)
) # 匹配日期(YYYY-MM-DD)
template_time = Combine(
Word(nums, exact=2) + ":" + Word(nums, exact=2) + ":" + Word(nums, exact=2)
) # 匹配时间(HH:MM:SS)

# 定义完整模式
pattern = (
template_starting # 匹配固定的字符串 "use time: "
+ template_date("login_date") # 匹配登录日期,并将其命名为 login_date
+ " " # 匹配空格
+ template_time("login_time") # 匹配登录时间,并将其命名为 login_time
+ StringEnd() # 确保匹配到行尾
)

# 逐行解析日志内容
login_counts = {} # 用于存储每天的登录次数
for line in log_content.splitlines(): # 按行分割日志内容
line = line.strip() # 去除行首尾的空格和换行符
if not line: # 跳过空行
continue
parsed_result = pattern.searchString(line) # 解析每一行
print(f"解析行:{line} -> 解析结果:{parsed_result}") # 打印每一行的解析结果
if parsed_result:
login_date = parsed_result[0].login_date # 提取登录日期
if login_date in login_counts:
login_counts[login_date] += 1 # 如果日期已存在,增加计数
else:
login_counts[login_date] = 1 # 如果日期不存在,初始化计数

return login_counts


if __name__ == "__main__":
# 示例日志内容
log_content = """
use time: 2025-01-13 20:11:33
use time: 2025-01-13 20:11:42
use time: 2025-01-13 22:42:21
use time: 2025-01-13 22:42:31
use time: 2025-01-14 22:38:16
use time: 2025-01-14 22:38:25
use time: 2025-01-14 23:02:20
use time: 2025-01-15 11:13:09
use time: 2025-01-15 11:13:59
use time: 2025-01-15 11:16:25
use time: 2025-01-15 11:33:54
use time: 2025-01-15 11:34:55
use time: 2025-01-15 11:36:09
use time: 2025-01-15 11:36:23
use time: 2025-01-15 11:37:54
use time: 2025-01-15 11:38:30
use time: 2025-01-15 13:58:01
use time: 2025-01-15 13:58:40
use time: 2025-01-15 14:00:26
use time: 2025-01-15 14:01:57
use time: 2025-01-15 14:03:43
use time: 2025-01-15 14:05:17
use time: 2025-01-15 17:56:19
use time: 2025-01-15 18:53:24
use time: 2025-01-15 19:00:06
use time: 2025-01-15 19:04:23
use time: 2025-01-15 19:18:19
use time: 2025-01-15 19:21:34
use time: 2025-01-15 19:30:49
use time: 2025-01-15 19:33:37
use time: 2025-01-15 19:42:22
use time: 2025-01-15 20:03:49
use time: 2025-01-15 20:08:52
use time: 2025-01-15 20:44:49
"""

# 解析登录日志
parsed_results = analysis_logs_login(log_content)
print(parsed_results)


# if __name__ == "__main__":
# # 读取日志文件
# with open("Temp/test_qrs.log", "r") as f:
# log_content = f.read() # 将日志文件内容读取到 log_content 变量中

# # analysis_logs(log_content)

# # 读取登录日志文件
# with open("Temp/test_login.txt", "r") as f:
# log_content = f.read() # 将日志文件内容读取到 log_content 变量中
# print(log_content)
# print("====================")
# # 解析登录日志
# parsed_results = analysis_logs_login(log_content)
# print(parsed_results)

  • 标题: Pyparsing
  • 作者: Sunmy
  • 创建于 : 2025-04-30 17:05:39
  • 更新于 : 2025-06-29 21:05:24
  • 链接: https://ldspdvsun.github.io/cmchvp8g7003ih0gb7q931oba/
  • 版权声明: 版权所有 © Sunmy,禁止转载。
评论