Python 3.5:使用空格格式化字符串

Python 3.5:使用空格格式化字符串,python,Python,我见过类似的问题,但没有一个能解决这个问题。我有一个使用+、-、*或/运算符的计算器表达式,我想对其进行标准化,以便有人输入的任何内容都与我的程序所需的内容一致 我的程序需要一个格式为“10-7*5/2+3”的字符串,每个值前后都有空格。我想把别人输入的任何东西,比如“10-7*5/2+3”或“10-7*5/2+3”,转换成我指定的第一种格式 我的第一个想法是将字符串转换为一个列表,然后在字符串之间加上空格,并将前后的空格连接起来,但明显的问题是“10”被拆分为“1”和“0”,并在连接后显示为“

我见过类似的问题,但没有一个能解决这个问题。我有一个使用+、-、*或/运算符的计算器表达式,我想对其进行标准化,以便有人输入的任何内容都与我的程序所需的内容一致

我的程序需要一个格式为“10-7*5/2+3”的字符串,每个值前后都有空格。我想把别人输入的任何东西,比如“10-7*5/2+3”或“10-7*5/2+3”,转换成我指定的第一种格式

我的第一个想法是将字符串转换为一个列表,然后在字符串之间加上空格,并将前后的空格连接起来,但明显的问题是“10”被拆分为“1”和“0”,并在连接后显示为“10”

s = s.replace(" ", "")

if s[0] == "-":
    s = "0" + s
else:
    s = s 

s = " " + " ".join(list(s)) + " "
我在想也许用正则表达式做点什么可能会有所帮助,但我不确定如何将其付诸实施。我在心理上的一个主要失误是,当我这样做的时候,不要让“10”和其他高阶数字分裂成它们的组成部分

我使用的是python 3.5

解决方案 如果您只处理非常简单的计算器表达式(即数字和操作数),则有一个想法。如果还有其他可能的元素,只需调整正则表达式即可

使用正则表达式提取相关片段,忽略空格,然后使用联接将它们重新组合在一起

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+
意味着匹配一行中的一个或多个数字

第二位:
[…]
是字符集表示法。它意味着匹配集合中任何一个字符中的一个。现在,
+
-
*
都是特殊的正则表达式字符,因此必须用反斜杠将它们转义。正斜杠并不特殊,因此不需要转义。所以
[\+,\-,\*,/]
意味着匹配+,-,*,/


两个正则表达式之间的
|
是您的标准
运算符。因此,请匹配第一个表达式或第二个表达式。括号是正则表达式中的组符号,表示您实际希望返回的正则表达式的哪一部分。

我建议采用简单易行的方法;删除所有空格,然后逐个字符遍历字符串,在每个运算符符号之前和之后添加空格

任何一行中有两个运算符的内容都将是无效语法,因此您可以将其留给现有的计算器代码来抛出错误

 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

正如@fukanchik所建议的,这通常是以相反的方式完成的,比如将输入字符串分解为基本组件,然后根据需要重新组装

我想说,使用正则表达式是正确的,因为它非常适合解析这种输入(非常适合,因为您不需要编写更高级的解析器)。为此,只需将所有符号定义为小正则表达式:

lexeme_regexes = [r"\+", "-", r"\*", "/", "\d+"]
然后组装一个大正则表达式,用于“遍历”输入字符串:

regex = re.compile("|".join(lexeme_regexes))
lexemes = regex.findall("10 - 7 * 5 / 2 + 3")
要获得规范化表单,只需重新组装它:

normalized = " ".join(lexemes)

这个例子并不能保证所有的操作符都被空白分割,这需要更多的努力。

为什么程序如此严格?我本来希望一些以数学表达式作为输入的东西能够解析它自己的文本来处理它需要处理的值。。。你确定你没有在这里重新发明轮子吗?通常的方法是相反的:在这个过程中分成
词素
“吃”空格。我有另一个函数,它在表达式中查找第一个数字,从一个设置的位置解析(在本例中是s[0]),如果数字为0,则查找第一个数字,那它就找不到第一个号码了。同样,我有一些函数可以找到操作符,如果它向前移动到下一个位置并落在操作符上,它将看不到该操作符。这就是为什么我需要在两者之间加空格的原因。所以-你想写一个函数来解析一些缺少空格/有过多空格的文本,使它成为你写的另一个函数的格式,这个函数对空格要求非常严格。。。你能不能-我不知道。。。只是让原来的函数对空格不那么严格?为什么不:1:定义运算符。2:通过运算符将输入字符串拆分为原子。3:清理每个原子中的空格/不需要的字符?这对我来说确实有效,我要坐下来看看注册表,确保我真正了解那里发生了什么,因为我没有太多地使用它。@Destroxia是一种令人钦佩的情绪。我已经为您添加了正则表达式的解释。