正则表达式来处理不同数量的变量

Regex to handle a varying number of variables

我正在尝试更改如下所示的字符串:

s = 'g1 & g2 & (X~(~g1 & ~g2) & ~o1) & (XX~(~g1 & ~g2) & ~o1 & X~o1)'

对此:

'g1_0 & g2_0 & (~(~g1_1 & ~g2_1) & ~o1_0) & (~(~g1_2 & ~g2_2) & ~o1_0 & ~o1_1)'

所以基本上我将附加到每个变量 _#(下划线和数字)作为它前面的 X 的数量并删除 X。问题主要出现在 X 位于括号之前并且我事先不知道括号中有多少变量和逻辑运算符时。

我尝试在 Python 中执行此操作。我从最多的 X 开始倒退(因为,如果我开始寻找 g1,它们都会改变)。所以这是序列:

import re
xs = 'X'*n
while n>0:
  # this is for when we have parentheses
  s = re.sub('%s([~]*)([(]+[~]*[a-zA-Z]+[0-9]+) ([&|]*) ([~]*[a-zA-Z]+[0-9]+)([)]+)'%xs, \
                          r'_%d  _%d'%(n,n), s)
  # this is for normal variables
  s = re.sub('%s([~]*[a-zA-Z]*[0-9]*)'%xs, r'_%d'%n, s) 
  xs = xs[:-1]
  n -= 1

并下降到没有 X。 问题是我不想强加 'o/g &/| o/g' 的结构。我希望它是可变长度的名称和运算符,但仍分配正确的名称。例如,处理:

XX(~g1 & ~g2 | ~k3)  --> (~g1_2 & ~g2_2 | ~k3_2)

如何使用 Regex 实现?

您可以使用递归 re:

import re
def rep_x(d, c = 0):
   s, f = '', 0
   while d:
      if d[0] == ')':
         return s+')', d[1:]
      if d[0] == '(':
         [_s, d], f = rep_x(d[1:], c = c+f), 0
         s += '('+_s
      elif (x:=re.findall('^X+', d)):
         d = d[(f:=len(x[0])):]
      elif (x:=re.findall('^\w+', d)):
         s, f, d = s + x[0]+'_'+str(f+c), 0, d[len(x[0]):]
      else:
         s, d = s+d[0], d[1:]
   return s, d

r1, _ = rep_x('g1 & g2 & (X~(~g1 & ~g2) & ~o1) & (XX~(~g1 & ~g2) & ~o1 & X~o1)') 
r2, _ = rep_x('XX(~g1 & ~g2 | ~k3)')          

输出:

'g1_0 & g2_0 & (~(~g1_1 & ~g2_1) & ~o1_0) & (~(~g1_2 & ~g2_2) & ~o1_0 & ~o1_1)'
'(~g1_2 & ~g2_2 | ~k3_2)'