python3字符串内括号匹配分析器 匹配分析字符串内括号的匹配闭合情况,可通过print打印匹配情况,高亮显示错误处。
思路,遍历字符串,检测到起始括号后加入到open队列中(位置,字符),检测到闭合括号后检测队列最后一位是否是对应的起始括号,是则open队列最后一位出列,否则把为匹配起始的符号进入close括号队列记录(位置,字符),遍历完成后,如果open,close队列均为空则符合匹配规则,否则不符合。
最后通过 .result 属性获得匹配状态信息
.info 属性获得匹配的分析文本
.print() 方法打印匹配字符串信息,背景显示红色字符为未闭合的括号,背景显示蓝色的未起始括号的字符。
高亮显示需要 import colorama
报错未安装可以安装包 pip install colorama
废话不多,直接上代码
此代码可即拿即用。
'''
Author: liwenjun
Date: 2022-10-20 15:54:59
LastEditors: liwenjun
LastEditTime: 2022-10-24 17:56:57
Description: 字符串内括号匹配分析器 匹配分析字符串内括号的匹配闭合情况
email:121959858@qq.com, www.moli666.com
'''
import colorama
colorama.init(autoreset=True)
class String:
'''
字符串内括号匹配分析器
Parse a string, determine if the parentheses are paired properly.
- string = String("a(c b)v(a 1<([“(])”)>")
- print(string.result) #输出结果
(False, [[8, '('], [12, '<'], [13, '('], [14, '[']], [[17, ']'], [20, ')'], [21, '>']])
- print(string.info) #输出分析解析文本
- string.print() #控制台输出结果高亮错误位置提示
'''
#匹配括号字典
#可以根据需求添加,已添加(),[],{},<>
SYMBLO_DICT ={")":"(","]":"[","}":"{",">":"<","’":"‘","”":"“"}
def __init__(self, string):
'''
初始化字符串并进行括号匹配分析
- params: string
- resulut 判断结果调用result属性获取
'''
self.string = string
self.symbol_l, self.symbol_r = self.SYMBLO_DICT.values(), self.SYMBLO_DICT.keys() #提取左括号右
self.open_symbol_queue = [] #定义open字符队列
self.close_symbol_queue = [] #定义close字符队列
self.error_place = -1
self.paired()
def paired(self):
'''
判断字符串是否匹配括号
- params: string
- return: resulut 返回判断结果(并打印结果True为good,False为bad)
'''
for i, symbol in enumerate(self.string):
#遍历字符串
if self.string[i] in self.symbol_l:
#判断当前字符是否为左括号
#是则放入symbol_queue列表末尾
self.open_symbol_queue.append([i+1, symbol])
elif self.string[i] in self.symbol_r:
#判断当前字符是否为右括号
#是进行下一步检测
if len(self.open_symbol_queue) == 0:
#检测open_symbol_queue列表是否为空
#检测失败,非上一次匹配的括号,判断结果为False
#为空则非上一次匹配的括号,判断结果为False
self.error_place = i+1
self.close_symbol_queue.append([i+1, symbol])
else:
l_i, l_symbol = self.open_symbol_queue[-1]
if self.SYMBLO_DICT[symbol] == l_symbol:
#检测symbol_queue列表最后进入的匹配右括号成功
self.open_symbol_queue.pop()#open_symbol_queue列表最新一位出列
else:
#检测失败,非上一次匹配的括号,判断结果为False
#为空则非上一次匹配的括号,判断结果为False
self.error_place = i+1
self.close_symbol_queue.append([i+1, symbol])
if len(self.open_symbol_queue):
self.error_place = self.open_symbol_queue[0][0]
def __result(self):
'''
获取分析结果文本
- return: 返回文本结果,用于阅读分析。
'''
...
if self.error_place > -1:
info = "Brackets not paired properly!"
else:
info = "Brackets are paired properly!"
if len(self.close_symbol_queue):
info = info + "\nNo opened Brackets: " + str(self.close_symbol_queue)
if len(self.open_symbol_queue):
info = info + "\nNo closed Brackets: " + str(self.open_symbol_queue)
return info
@property
def info(self):
'''
获取分析结果文本属性 string.info
- return: 返回文本结果,用于阅读分析。
'''
return self.__result()
@property
def result(self,):
'''
获取分析结果文本属性 string.result
- return: 返回tuple 元组(True,[no_close_symbol],[no_open_symbol])
'''
return (False if self.error_place>-1 else True, self.open_symbol_queue, self.close_symbol_queue)
def print(self,):
'''
打印匹配状态,未匹配正确的颜色高亮显示
- print控制台输出
'''
mark_info = ""
open_symbol_no = [symbol[0] for symbol in self.open_symbol_queue]
close_symbol_no = [symbol[0] for symbol in self.close_symbol_queue]
for i, symbol in enumerate(self.string):
new_symbol = symbol
if i+1 in open_symbol_no:
#new_symbol = f'\033[1;31;40m{symbol}\033[0m'
new_symbol = colorama.Back.RED + symbol + '\033[0m'
if i+1 in close_symbol_no:
#new_symbol = f'\033[1;34;40m{symbol}\033[0m'
new_symbol = colorama.Back.BLUE + symbol + '\033[0m'
mark_info = mark_info + new_symbol
print(mark_info)
if __name__ == '__main__':
#string = String("a(b)c a(c[g]3 {}2)")#匹配成功的字符串
string = String("a(b)c a(c[g]3 {[}2>)")#匹配失败的字符串
print(string.result) #输出结果
print(string.info) #输出分析解析文本
string.print() #控制台输出结果高亮错误位置提示