27
社区成员




Python 的字符串处理, 一个朴实无华的四则运算计算器,批量计算小学生四则运算表达式
# -*- coding: UTF-8 -*-
import re
def naive_calc(code):
# TODO(You): 请在此实现简易四则运算
def test():
code = '''
1+2
3+4
5-3
4*3
10/2
'''
naive_calc(code)
if __name__ == '__main__':
test()
请选出下列能正确实现这一功能的选项。
在正则表达式中,\s
是一个特殊的字符类,代表任何空白字符,包括空格、制表符(Tab)、换行符、回车符和其他 Unicode 空白字符。字符类 * 表示前面的字符类(在这里是 \s)可以出现零次或多次。
所以,在正则表达式 \s*(\d+)([+-*/])(\d+)\s* 中:
(\d+)
匹配一个或多个数字字符,并将其捕获为另一个分组。\s
和 * 用于模式的不同部分,\s
是一个字符类,而 * 是一个表示数量的元字符。 结合在一起 \s* 表示匹配任意数量的空白字符。这个正则表达式用来匹配简单的四则运算表达式。下面分别解释各个部分的含义:
\d
是匹配任意数字的元字符,而后面的 + 表示匹配一个或多个前面的元素。括号 () 表示捕获组,用于后续引用这个匹配到的内容。group(2)
获取运算符和 group(3) 获取右操作数。这些捕获组可以用于后续的四则运算逻辑。正确实现一个简易四则运算计算器的代码是选项 D。下面是对每一个选项的分析:
A: 这个选项没有把从正则表达式获取的字符串转换成整数进行计算,导致它只会将字符串拼接在一起而不是执行数学运算。同时,这个选项还使用了错误的方法来判断除数是否为零。
B: 这一选项的正则表达式使用了错误的顺序,在 re.match 函数中第一个参数应该是模式串,第二个参数是要匹配的字符串。这个错误会导致 re.match 不能正确执行。
C: 此选项中提取代码行的逻辑是错误的,因为 if l.strip() == '' 将会排除所有非空行。正确的逻辑应该是对空行执行 strip() 后不等于空字符串的检查。此外,这段代码也没有对正则表达式匹配失败的情况做错误处理。
D: 这是正确的实现。它首先分割字符串获取非空行,然后利用正则表达式对每行代码进行匹配,提取左操作数、运算符和右操作数。接着,它将字符串转换为整数,并根据运算符执行相应的四则运算。最后,它正确地检查除数是否为零以避免除以零的情况。
因此,正确的实现是:
def naive_calc(code):
code_lines = [l for l in code.split('\n') if l.strip() != '']
for line in code_lines:
ret = re.match("\s*(\d+)([\+\-\*\/])(\d+)\s*", line)
if not ret: # 如果匹配失败,则跳过这行
continue
left = ret.group(1)
op = ret.group(2)
right = ret.group(3)
if op == '+':
print('{}+{}={}'.format(left, right, int(left)+int(right)))
elif op == '-':
print('{}-{}={}'.format(left, right, int(left)-int(right)))
elif op == '*':
print('{}*{}={}'.format(left, right, int(left)*int(right)))
elif op == '/':
right_int = int(right)
if right_int != 0:
print('{}/{}={}'.format(left, right, int(left)/right_int))
else:
print('Error: Division by zero') # 正确处理除以零的错误
看的眼睛疼
# 代码通过正则表达式匹配输入的每一行中的第一个数字、运算符、第二个数字,
# 并根据不同的运算符进行相应的计算并输出结果。其中,如果出现了除数为0的
# 情况,则不会输出结果。
# 代码中的 test() 函数会调用 naive_calc() 函数,传入一段字符串作为
# 待处理的代码,即 code 变量中的多行字符串。函数首先将这段代码按照换行
# 符分割成多行,然后对每一行进行处理。通过正则表达式提取出每一行中的运算
# 式,并对运算符进行判断,进行不同的计算并输出结果。最终输出的结果会显示
# 在控制台中。
# -*- coding: UTF-8 -*-
import re
def naive_calc(code):
code_lines = [l for l in code.split('\n') if l.strip() != '']
# 这句代码是用来将多行字符串 code 按照换行符分割成多个行字符串,并将这
# 些行字符串保存在一个列表中。
# 具体来说,代码首先调用字符串对象的 split() 方法,将字符串按照换行符
# 分割成多个子字符串,然后将这些子字符串保存在一个列表中。由于在处理多
# 行字符串时,可能会出现包含多个连续空格或制表符的情况,因此代码中使用
# strip() 方法来去掉每个行字符串首尾的空格和制表符,并使用 if 条件语
# 句来过滤掉空行,即长度为0的行字符串。最终得到的列表 code_lines 中,
# 每个元素就是一行非空的字符串。这个"列表" code_lines 将会作为后面的处
# 理输入代码的数据源。
# print(code_lines) 输出结果如下
# [' 1+2', ' 3+4', ' 5-3', ' 4*3', ' 10/2']
for line in code_lines:
print(line)
ret = re.match("\s*(\d+)([\+\-\*\/])(\d+)\s*", line)
# 这个正则表达式可以用来匹配简单的数学表达式,如 2+3、 5 /6等等。
# 这个正则表达式包含了三个捕获组:
# 第一个捕获组 \s*(\d+) 匹配任意数量的空格,然后捕获一个或多个数字。
# 这个捕获组用于匹配表达式中的第一个数字。
# 第二个捕获组 ([\+\-\*\/]) 匹配加号、减号、乘号或除号。这个捕获组
# 用于匹配表达式中的运算符。
# 第三个捕获组 (\d+) 匹配一个或多个数字,并捕获它们。这个捕获组用于
# 匹配表达式中的第二个数字。
# 整个表达式用括号括起来,表示需要捕获整个匹配结果,以便后续的处理。
# 在每个数字和运算符周围的空格使用了 \s* 来匹配任意数量的空格,以防止
# 输入表达式时出现意外的空格。
# 注意,这个正则表达式只能匹配简单的数学表达式,而不能处理复杂的表达式
# ,例如带有括号、指数、函数等等。如果需要处理更复杂的表达式,可能需要
# 使用更复杂的正则表达式或其他解析器。
# print(ret.group()) 打印结果为: 1+2(注意前面是有空格的)
left = ret.group(1)
op = ret.group(2)
right = ret.group(3)
# 这几行代码将正则表达式匹配得到的结果分别赋值给了left、op和right三个
# 变量,把空格去掉了,具体来说:
# ret.group(1)代表正则表达式中第1个括号捕获到的内容,即匹配到的第1个数字;
# ret.group(2)代表正则表达式中第2个括号捕获到的内容,即匹配到的操作符;
# ret.group(3)代表正则表达式中第3个括号捕获到的内容,即匹配到的第2个数字。
# 这些变量会在接下来的代码中被使用,计算出对应表达式的结果。
# print(left, op, right) 打印结果为:1+2(空格没有啦!)
if op == '+':
print('{}+{}={}'.format(left, right, int(left) + int(right)))
# 因为op变量中存储了四则运算符,所以根据四则运算符加减乘除 +-*/ 来判断我们该
# 做哪项运算。由于我们取出的是字符串,所以我们在计算时候需要将字符串转为数字才
# 行。即:
# int(left) + int(right)
elif op == '-':
print('{}-{}={}'.format(left, right, int(left) - int(right)))
elif op == '*':
print('{}*{}={}'.format(left, right, int(left) * int(right)))
elif op == '/' and right != '0':
print('{}/{}={}'.format(left, right, int(left) / int(right)))
def test():
code = '''
1+2
3+4
5-3
4*3
10/2
'''
naive_calc(code)
test()
没仔细看还以为那个‘’是双引号
啊,我还以为是match的用法问题,不是要先写那个正则表达式再写字符串吗?
正确答案贴到python中都没有输出结果
def naive_calc(code):
code_lines = [l for l in code.split() if l.strip() == '']
for line in code_lines:
ret = re.match("\s*(\d+)([+-*/])(\d+)\s*", line)
left = ret.group(1)
op = ret.group(2)
right = ret.group(3)
if op == '+':
print('{}+{}={}'.format(left, right, int(left)+int(right)))
elif op == '-':
print('{}-{}={}'.format(left, right, int(left)-int(right)))
elif op == '*':
print('{}*{}={}'.format(left, right, int(left)*int(right)))
elif op == '/' and right != '0':
print('{}/{}={}'.format(left, right, int(left)/int(right)))
开头的for部分是遍历code_lines列表中的所有元素,每次遍历的结果存入line变量中。其中,code_lines是一个列表,它包含了code字符串中所有的非空行。
def naive_calc(code):
code_lines = [l.strip(' ') for l in code.split('\n') if l.strip() != '']
print(code_lines)
for line in code_lines:
if '+' in line:
a, b = line.split('+')
print(f'{line}={int(a) + int(b)}')
elif '-' in line:
a, b = line.strip(' ').split('-')
print(f'{line}={int(a) - int(b)}')
elif '*' in line:
a, b = line.split('*')
print(f'{line}={int(a) * int(b)}')
else:
a, b = line.split('/')
print(f'{line}={int(a) / int(b)}')
字符串要转化为整数型才能进行四则运算
四则运算需要将字符串转换为int才可以进行
这题出的,表面上是考四则运算,实则是考数据类型