我见过类似的问题,但没有一个能解决这个问题。我有一个使用+, - ,*或/运算符的计算器表达式,我想对它进行标准化,以便任何人输入的内容与我的程序想要的内容一致......
我的程序想要一个格式为“10 - 7 * 5/2 + 3”的字符串,前后各个空格,以及每个值之间的空格。我想接受某人输入的任何内容,例如“10-7 * 5/2 + 3”或“10-7 * 5/2 + 3”,并将其设为我指定的第一种格式。
我的第一个想法是将字符串转换为列表,然后用中间的空格连接并连接前端和末尾的空格,但明显的问题是'10'被拆分为'1'和'0'并在加入后出现'1 0'。
s = s.replace(" ", "")
if s[0] == "-":
s = "0" + s
else:
s = s
s = " " + " ".join(list(s)) + " "
我在想,也许用RegEx做些什么可能会有所帮助,但我并不完全确定如何将其付诸行动。对我来说,精神上的主要障碍就是让“10”和其他更高阶的数字在我这样做时不会分裂成他们的成分。
我在python 3.5中。
答案 0 :(得分:3)
如果你只处理非常简单的计算器表达式(即数字和操作数),那就有一个想法。如果你还有其他可能的元素,你只需要调整正则表达式。
使用正则表达式提取相关部分,忽略空格,然后使用连接将它们重新组合在一起。
ACTION_OPEN_DOCUMENT_TREE
def compose(expr):
elems = re.findall(r'(\d+|[\+,\-,\*,/])', expr) # a group consists of a digit sequence OR an operand
return ' ' + ' '.join(elems) + ' ' # puts a single space between all groups and one before and after
compose('10- 7*5/2 + 3')
# ' 10 - 7 * 5 / 2 + 3 '
compose('10-7*5/2+3')
# ' 10 - 7 * 5 / 2 + 3 '
来电的内容是正则表达式:re.findall
第一位:r'(\d+|[\+,\-,\*,/])'
表示匹配一位数。 \d
表示匹配前一个表达式的一个或多个 。因此,+
意味着匹配一行中的一个或多个数字。
第二位:\d+
是字符集表示法。这意味着匹配集合中任何字符之一。现在[...]
,+
,-
都是特殊的正则表达式字符,因此您必须使用反斜杠转义它们。正斜杠并不特殊,因此不需要转义。因此,*
表示匹配+, - ,*,/ 中的任何一个一个。
两个正则表达式之间的[\+,\-,\*,/]
是您的标准|
运算符。所以匹配第一个表达式或第二个表达式。并且括号是正则表达式中的组表示法,表示您实际想要返回的正则表达式的部分。
答案 1 :(得分:1)
我建议采取一种简单易行的方法;删除所有空格,然后逐个字符地逐字符串,在每个运算符符号之前和之后添加空格。
无论如何,连续两个运算符的任何内容都将是无效的语法,因此您可以将其留在现有的计算器代码中以抛出错误。
sanitised_string = ""
for char in unformatted_string_without_spaces:
if char in some_list_of_operators_you_made:
sanitised_string += " " + char + " "
else:
sanitised_string += char
答案 2 :(得分:1)
就像@fukanchik建议的那样,这通常是反向完成的,就像将输入字符串分解为基本组件一样,然后根据需要重新组装它。
我说你使用RegEx是在正确的轨道上,因为它非常适合解析这种输入(完美的,因为你不需要编写更高级的解析器)。为此,只需将所有符号定义为小正则表达式:
lexeme_regexes = [r"\+", "-", r"\*", "/", "\d+"]
然后组装一个大的正则表达式,用于“走”输入字符串:
regex = re.compile("|".join(lexeme_regexes))
lexemes = regex.findall("10 - 7 * 5 / 2 + 3")
要获得标准化表格,请再次组装:
normalized = " ".join(lexemes)
这个例子并不能确保所有运算符都被空格分开,这需要更多的努力。