Regex 将算术表达式的字符串拆分为列表及其运算符和数字(包括小数)

Regex Split string of arithmetic expression into list with its operators and numbers (decimal included)

我已经编写了这段代码,但我认为这不是最好的方法。

import re
notation = "41*(5.5+6-(8/2^3)-7)-1"
n2 = [x[0] for x in re.findall(r"(\d+(\.\d+)?)",notation)]
n2.reverse()
m = []
x = True

for z in notation:
    if z.isdigit() and x:
        m.append(n2.pop())
        x = False
    if not z.isdigit() and z != ".": 
        m.append(z)
        x = True

预期输出为:

m = ['41', '*', '(', '5.5', '+', '6', '-', '(', '8', '/', '2', '^', '3', ')', '-', '7', ')', '-', '1']

我认为这段代码有一种硬编码,我的疑问是您如何以更好的方式制作它?

这是使用 re.finditer, with this re 表达式的一种方法:

>>> import re
>>> m =[]
>>> s = "41*(5.5+6-(8/2^3)-7)-1"
>>> for match in re.finditer(r'[+\-*^/()]|[0-9.]+', s):
        if match:
            m.append(match.group(0))


>>> m
['41', '*', '(', '5.5', '+', '6', '-', '(', '8', '/', '2', '^', '3', ')', '-', '7', ')', '-', '1']

使用regex findall,你可以得到你想要的结果!

正则表达式:

re.findall('[0-9.]+|.',m)

因此,

>>> import re
>>> notation  = '41*(5.5+6-(8/2^3)-7)-1'
>>> m = re.findall('[0-9.]+|.',notation )
>>> print m
['41', '*', '(', '5.5', '+', '6', '-', '(', '8', '/', '2', '^', '3', ')', '-', '7', ')', '-', '1']

如果您对符号有特定要求 +\-*^/() 那么您可以使用

>>> m = re.findall('[0-9.]+|[+\-*^/()]',notation)
>>> print m
['41', '*', '(', '5.5', '+', '6', '-', '(', '8', '/', '2', '^', '3', ')', '-', '7', ')', '-', '1']

会给你想要的结果!

希望对您有所帮助!

re.findall 与旨在查找 numbersoperators 的正则表达式一起使用。

  • 数字模式是[0-9.]+,它得到所有数字和小数点。
  • 单字符运算符模式是 [*/+\-\^],它可以进行乘法、除法、加法、减法(转义,因为 - 是一个特殊的正则表达式字符)和求幂(也转义,因为 - 是一个特殊的正则表达式字符)。

例如:

>>> import re
>>> notation = "41*(5.5+6-(8/2^3)-7)-1"
>>> re.findall(r'[0-9.]+|[*/+\-\^]', notation)
['41', '*', '5.5', '+', '6', '-', '8', '/', '2', '^', '3', '-', '7', '-', '1']

可以进一步细化数字模式以查找最多单个小数位。 (?:[0-9]+\.[0-9]+)|(?:[0-9]+\.)|(?:\.?[0-9]+)。这样可以解析3.14 + 42. + .707 + 6.

中的数字

要处理多字符运算符,将它们放在链中的最前面(以防止单个字符首先匹配)。例如,(?:\*\*|\*|/|\+|\-) 将解析 2 ** 5 / 6 + 7 * 3 - 1.

中的运算符

希望这有助于您进行词法分析器实验:-)