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 与旨在查找 numbers 或 operators 的正则表达式一起使用。
- 数字模式是
[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
.
中的运算符
希望这有助于您进行词法分析器实验:-)
我已经编写了这段代码,但我认为这不是最好的方法。
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 与旨在查找 numbers 或 operators 的正则表达式一起使用。
- 数字模式是
[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
.
希望这有助于您进行词法分析器实验:-)