在字符串中查找数字,修改并重新加入

时间:2013-05-05 23:45:13

标签: python regex

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似乎是数字匹配部分。 它可能比我需要的要复杂一点,但主要是我不知道如何将它与保持分离器位相结合。

2 个答案:

答案 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