本题的算法标签是「栈」,标准做法是调度场算法(shunting-yard):从左到右扫描规则串,用输出序列保存已经确定顺序的 RPN 单词,用操作符栈暂存还没轮到输出的操作符和左括号。
第一步:分词。 规则串里可能有连续空格,括号也可能紧贴单词(例如 NOT(ERROR))。因此不能简单按空格 split,而要逐字符扫描:
( 或 ) 单独作为一个 token;NOT / AND / OR)。系统中日志采集模块支持用户配置日志过滤规则。为了避免每次匹配都重新解析规则,需要开发一个规则解析器。
给定一个日志规则字符串,实现一个函数,把规则转换成逆波兰表达式(RPN,即后缀表达式)。
日志关键字(操作数)只能是以下 5 个字符串,必须完全一致,包括大小写,规则保证不会出现其它关键字:
ERRORNETWORKTIMEOUTDISKCPU操作符只有以下 3 种;AND、OR 同级时从左到右结合,NOT 按右结合处理:
| 符号 | 类型 | 含义 | 优先级(值越大优先级越高) | 结合性 |
|---|---|---|---|---|
NOT |
一元操作符 | 逻辑非 | 3 | 右结合 |
AND |
二元操作符 | 逻辑与 | 2 | 左结合 |
OR |
二元操作符 | 逻辑或 | 1 | 左结合 |
规则中可能包含括号,用于显式改变结合顺序,保证括号成对出现且嵌套正确:
(:进入新的运算层级;):结束当前运算层级。输入只有一行,是一条规则字符串 rule(不含首尾引号),例如:
ERROR AND (NETWORK OR TIMEOUT)
规则字符串满足:
输出只有一行,为转换后的 RPN:按后缀表达式顺序输出各个单词(操作数与操作符),单词之间用一个半角空格分隔,行末换行。
输出中不要带引号、逗号或方括号。例如 ERROR AND NETWORK 的输出是:
ERROR NETWORK AND
输入
ERROR AND NETWORK
输出
ERROR NETWORK AND
说明
ERROR、NETWORK 是 AND 的两个运算对象,先按顺序写出两个操作数,再把 AND 放到后面,得到 ERROR NETWORK AND。
输入
ERROR AND (NETWORK OR TIMEOUT)
输出
ERROR NETWORK TIMEOUT OR AND
说明
括号使 NETWORK OR TIMEOUT 先结合成一组,括号内展开为 NETWORK TIMEOUT OR;外层再与 ERROR 做 AND,最终得到 ERROR NETWORK TIMEOUT OR AND。
输入
DISK
输出
DISK
一个操作数不需要任何操作符,直接输出它本身。
NOT 是一元前缀操作符,优先级最高,只作用于紧跟在其后的一个操作数,或紧跟在其后的一整个括号表达式。AND 的优先级高于 OR;AND、OR 同级时从左到右结合。NOT 连续出现时按右结合处理,例如 NOT NOT ERROR 等价于 NOT (NOT ERROR),输出为 ERROR NOT NOT。例如 NOT ERROR OR TIMEOUT 中,NOT 只作用于 ERROR,不会把后面的 TIMEOUT 也吞进去,因此输出为 ERROR NOT TIMEOUT OR;而 NOT (ERROR OR TIMEOUT) 中 NOT 作用于整个括号,输出为 ERROR TIMEOUT OR NOT。
Scan the QR code below with WeChat to sign in
设置一个用户名,下一步用微信扫码完成注册
请使用微信扫描下方二维码完成注册