【问题标题】:Regex to handle a varying number of variables正则表达式处理不同数量的变量
【发布时间】:2021-11-09 23:13:15
【问题描述】:

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

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'\1\2_%d \3 \4_%d\5'%(n,n), s)
  # this is for normal variables
  s = re.sub('%s([~]*[a-zA-Z]*[0-9]*)'%xs, r'\1_%d'%n, s) 
  xs = xs[:-1]
  n -= 1

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

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

我该如何使用正则表达式?

【问题讨论】:

  • 我认为这对于正则表达式来说可能太复杂了。考虑一次解析字符串一个字符,使用状态机方法(状态是 X 的数量)
  • 如果括号只能嵌套一层,您仍然可以使用正则表达式,请参阅this Python demo。如果可以使用 PyPi 正则表达式库,会简单一些。
  • 谢谢@WiktorStribiżew,你的回答也很完美。

标签: python regex str-replace string-matching


【解决方案1】:

你可以使用递归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)'

【讨论】:

  • 完美运行!甚至比我预期的还要好(可以使用不仅仅是“[a-z][0-9]”的名称)。我需要使用调试器一步一步地跟踪它,以完全了解那里发生了什么。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
相关资源
最近更新 更多