使用REGEX解析带参数的线性方程

时间:2015-07-08 18:08:42

标签: python regex

我试图使用REGEX解析线性方程。公式如下:

2 * var1.val          + 7 * var2 + 9 * var3 = 1
3 * var1.val          + 4 * var2            = 9
param1.val * var1.val            + 4 * var3 = 7

系数可以是数字或参数。我希望得到结果:

[2,         7,  9
3,          4,  0
param1.val, 0,  4]

我用Google搜索并找到了一个示例代码,我修改了该代码以满足我的需要。它看起来像:

equations = [' 2 * var1.name + 7 * var2 + 9 * var3 = 1',
             ' 3 * var1.name + 4 * var2 = 9',
             ' param1.val * var1.name + 4 * var3 = 7']
augmented_matrix = {'__b__':[0]*3}                 # initialize the RHS vector
parse_ptrn = r'([+-]?[\d*|\w*][\*]+)(\w+\.?\w+)'        
parse_obj = re.compile(parse_ptrn)

for i in range(3):
    e = ''.join(equations[i].split())              # split and join to remove spaces
    left, right = e.split('=')                     # separate RHS and LHS

    try:
        augmented_matrix['__b__'][i] = float(right) # if possible convert RHS to float
    except:
        augmented_matrix['__b__'][i] = right
    # FOR LHS
    for coeff, var in parse_obj.findall(left):
        if coeff == '': coeff = 1
        elif coeff == '-': coeff = -1
        else:
            try:
                coeff = float(coeff.replace("*","")) # convert to float/Remove * from coeff
            except:
                coeff = coeff.replace("*","")
        if var not in augmented_matrix:
            augmented_matrix[var] = [0] * 3 
        augmented_matrix[var][i] = coeff
    print left, right
    print parse_obj.findall(left)

由于参数的原因,它无法正确解析第三个等式。对于第三个等式中的第一个系数,它给出了我的最后一个字母“l”而不是“param.val”。我相信REGEX ([+ - ]?[\ d * | \ w *] [\ *] +)应该能够在字符串的开头和*(数字或字符)之间找到任何内容

请帮帮我。

2 个答案:

答案 0 :(得分:1)

请尝试将其用于正则表达式:

parse_ptrn = r'([+-]?[\w.]*\*)(\w+\.?\w+)'

我将[\d*|\w*](即一个字符\d,星号*,管道|或字符\w)更改为{{ 1}}(即至少一个字符或小数点)。请注意,[\w.]+不是必需的,因为它是\d的子集(所有数字都是单词字符)。此外,您的原始代码不适用于多位数系数,例如\w,因为它只在10之前选择了一个字符。

请注意,由于第一个变量*前面缺少系数和var1.val + 4 * var2 = 9,因此对*等公式仍然不起作用。我将此作为练习留给您,但如果您遇到问题,只需对此答案进行评论,我会更新它以包含该案例(我假设您希望系数为var1.val情况)?

答案 1 :(得分:0)

作为旁注,如果你知道方程的顺序(如3),那就是
可以在一个正则表达式中完成所有操作。

 # ^(?=.*?\S+\s*\*\s*var[123]).*?(?:(\S+)\s*\*\s*var1.+?)?(?:(\S+)\s*\*\s*var2.+?)?(?:(\S+)\s*\*\s*var3.+?)?$

 ^ 
 (?=
      .*? \S+ 
      \s* \* \s* var [123] 
 )
 .*? 
 (?:
      ( \S+ )                       # (1)
      \s* \* \s* var1
      .+? 
 )?
 (?:
      ( \S+ )                       # (2)
      \s* \* \s* var2
      .+? 
 )?
 (?:
      ( \S+ )                       # (3)
      \s* \* \s* var3
      .+? 
 )?
 $     

输出:

 **  Grp 0 -  ( pos 0 , len 47 ) 
2 * var1.val          + 7 * var2 + 9 * var3 = 1  
 **  Grp 1 -  ( pos 0 , len 1 ) 
2  
 **  Grp 2 -  ( pos 24 , len 1 ) 
7  
 **  Grp 3 -  ( pos 35 , len 1 ) 
9  
-------------
 **  Grp 0 -  ( pos 49 , len 47 ) 
3 * var1.val          + 4 * var2            = 9  
 **  Grp 1 -  ( pos 49 , len 1 ) 
3  
 **  Grp 2 -  ( pos 73 , len 1 ) 
4  
 **  Grp 3 -  NULL 
-------------
 **  Grp 0 -  ( pos 98 , len 47 ) 
param1.val * var1.val            + 4 * var3 = 7  
 **  Grp 1 -  ( pos 98 , len 10 ) 
param1.val  
 **  Grp 2 -  NULL 
 **  Grp 3 -  ( pos 133 , len 1 ) 
4