import re
# 格式化字符串函数(消除一些错误的格式)
def format_string(string):
# 一系列的替换语句
string = string.replace("--", "-")
string = string.replace("-+", "-")
string = string.replace("++", "+")
string = string.replace("*+", "*")
string = string.replace("/+", "/")
string = string.replace(" ", "-")
return string
# 检查函数(检查输入的表达式是否合法)
def chek_expression(string):
check_result = True # 标志位
if not string.count("(") == string.count(")"): # 检查括号是否完整
print("输入错误,未匹配到完整括号!")
check_result = False
if re.findall('[a-pr-z]+', string.lower()): # 检查是否包含字母
print("输入错误,包含非法字符!")
check_result = False
return check_result
# 加减法函数
def add_minus(string):
add_regular = r'[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*' # 定义一个匹配的规则
sub_regular = r'[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*' # 同上
# 注解:[\-]? 如果有负号,匹配负号; \d+ 匹配最少一个数字; \.? 是否有小数点,有就匹配;\d* 是否有数字有就匹配
# \+ 匹配一个加号; [\-]?\d+\.?\d* 这几个同上
# 加法
while re.findall(add_regular, string): # 按照regular规则获取一个表达式,用while循环,把所有加法都算完
add_list = re.findall(add_regular, string)
for add_stars in add_list:
x, y = add_stars.split('+') # 获取两个做加法的数(以+号作为分割对象),分别赋给x和y
add_result = '+' + str(float(x) + float(y))
string = string.replace(add_stars, add_result) # 替换
string = format_string(string)
# 减法
while re.findall(sub_regular, string): # 用while循环,把所有减法都算完
sub_list = re.findall(sub_regular, string)
for sub_stars in sub_list:
x, y = sub_stars.split('-') # 获取两个做减法的数(以-号作为分割对象),分别赋给x和y
sub_result = '+' + str(float(x) + float(y))
string = string.replace(sub_stars, sub_result) # 替换
string = format_string(string)
return string
# 乘、除法函数
def multiply_divide(string):
regular = r'[\-]?\d+\.?\d*[*/][\-]?\d+\.?\d*' # 定义一个匹配的规则regular
while re.findall(regular, string):
expression = re.search(regular, string).group() # 按照regular规则获取一个表达式
# 如果是乘法
if expression.count('*') == 1:
x, y = expression.spilt('*')
mul_result = str(float(x) * float(y))
string = string.replace(expression, mul_result) # 计算结果替换原表达式
string = format_string(string) # 格式化
# 如果是除法
if expression.count('/') == 1:
x, y = expression.spilt('/')
div_result = str(float(x) / float(y))
string = string.replace(expression, div_result)
string = format_string(string) # 格式化
# 如果是阶乘
if expression.count('**') == 1:
x, y = expression.spilt('**')
pow_result = 1
for i in range(int(y)):
pow_result *= int(x)
string = string.replace(expression, str(pow_result))
string = format_string(string) # 格式化
return string
# 主程序
while True:
source = input("请输入表达式:") # 输入要计算的式子
if source == "Q": # 该判断语句只能写在前面,写后面会报错
exit() # 如果输入是Q,退出
elif chek_expression(source):
print("eval result: ", eval(source)) # eval() 是把其他类型转换为字符串
sourse = format_string(source)
if source.count("(") > 0:
stars = re.search(r'\([^()]*\)', source).group() # 去括号,得到括号里的字符串
replace_stars = multiply_divide(stars) # 将括号的表达式进行乘除运算
replace_stars = add_minus(stars) # 将乘除的结果进行加减运算
source = format_string(source.replace(stars, replace_stars)) # 用计算结果替换括号字符串
# 没有括号直接进行运算
else:
replace_stars = multiply_divide(source) # 乘除运算
replace_stars = add_minus(source) # 加减运算
source = source.replace(source, replace_stars)