Probem :
我有一个字符串,包含不同的数字,数学符号和单词,例如
str = ".1**2 + x/(10.0 - 2.E-4)*n_elts"
我想提取所有数字并保留数字之间的部分,以便稍后我可以将它们放在一起(在处理数字之后)。
lst = [".1", "**", "2", " + ", "x/(", "10.0", " - ", "2.E-4", ")*n_elts"]
将是许多可接受的结果之一。非数字的元素可以以任意方式进一步分割,因为下一步将是
"".join(process(l) for l in lst)
进程可能如下所示
(有关更好地检查l
的方法的建议值得欢迎):
def process(l):
try:
n = float(l)
except ValueError:
return l
else:
return work_on_it(l)
当前状态:
来自this answer我想出了如何保持分遣者并努力工作
lst = re.split('( |\+|\-|\*|/)', ".1**2 + x/(10.0 - 2.E-4)*n_elts")
现在我需要以某种方式避免拆分2.E-4
。
我试图找出一个正则表达式(vi语法,希望这是通用的) 这涵盖了可能出现的所有数字并思考
\d*\.\d*[E|e]*[|+|-]*\d*
应该没问题。
一种策略是以某种方式将其纳入re
。
我还发现related answer似乎是数字匹配部分。 它可能比我需要的要复杂一点,但主要是我不知道如何将它与保持分离器位相结合。
答案 0 :(得分:2)
一般注意事项:在内部角色类中,您不使用|
,因为它只是被视为要匹配的另一个角色。在字符类内部,允许的字符只是在彼此之后列出。
要真正解决您的问题:既然您仍然保留分隔符,那么您是否匹配数字或非数字并不重要?所以只需使用
lst = re.split(r'(\d*\.\d*[Ee]*[+-]*\d*)', ".1**2 + x/(10.0 - 2.E-4)*n_elts")
您可能希望稍微改进该数字正则表达式:
lst = re.split(r'((?:\d+\.\d*|\.?\d+)(?:[Ee][+-]?\d+)?)', ".1**2 + x/(10.0 - 2.E-4)*n_elts")
这样,您可以使小数点可选,但在它之前或之后至少需要一位数。这也使指数部分完全可选,但确保它存在时格式良好。 ?:
抑制捕获。否则这些内部组将与外部括号组相同,并将内部匹配的部分添加到split
的结果中 - 您不希望这样,因为这将为您提供完整的数字,指数前的部分和指数的分别。因此,您需要使用?:
来抑制捕获(除非您明确需要捕获,否则这通常是一个好习惯。)
最后,请注意使用原始字符串(字符串文字前面的r
)。没有这种逃避可以变得非常丑陋(因为你可能必须双重逃避某些正则表达式元字符)。在Python中,您应该始终使用原始字符串来表示正则表达式模式。
答案 1 :(得分:2)
你可以利用re.split()
利用捕获正则表达式返回奇数索引处的匹配example:
import re
s = ".1**2 + x/(10.0 - 2.E-4)*n_elts"
parts = re.split(r"([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?)", s)
parts[1::2] = [str(100 * float(f)) for f in parts[1::2]]
print("".join(parts))
# -> 10.0**200.0 + x/(1000.0 - 0.02)*n_elts
正则表达式来自Python and regex question, extract float/double value。