【问题标题】:Mapping Boolean formulas to Python set expressions将布尔公式映射到 Python 集合表达式
【发布时间】:2014-03-12 01:58:21
【问题描述】:

假设我有一个使用一组已知标记的布尔公式,例如:

  • 布尔运算符:andornot
  • 分组运算符:()

给定一个使用这些标记的布尔公式,例如:

F:(A or B) and not(A and C)

如何将此定义转换为集合运算符的 Python 表达式?

Fp = (x in A or x in B) and not(x in A and x in C)

有关此问题的背景信息,请参阅thread and accepted answer

【问题讨论】:

  • 不知道为什么你接受了显然并没有真正解决一般问题的链接答案。无论如何,您需要解析布尔表达式。您可能会发现 pyparsing 模块很有帮助。它附带了许多示例来帮助您入门。

标签: python regex parsing boolean numexpr


【解决方案1】:

请参阅set operations 的文档。您可以执行以下操作:

Fp = (A | B) - C

【讨论】:

    【解决方案2】:

    假设您的变量长度为一个字符:

    s = "(A or B) and not(A and C)"
    print re.sub("(?<![a-zA-Z])([A-Za-z])(?![A-Za-z])", "x in \\1", s)
    

    【讨论】:

      【解决方案3】:

      看起来基本上你要在任何不是你的令牌之一的东西前面加上x in。可能是这样的:

      tokens = ['and', 'or', 'not']
      grouping = ['(', ')']
      
      def resub(match):
          matchval = match.group(0)
          if matchval in tokens:
              return matchval
          return 'x in %s'%matchval
      
      s = "(A or B) and not(A and C)"
      
      re.sub('\w+', resub, s)
      '(x in A or x in B) and not(x in A and x in C)'
      

      它应该适用于被识别为单词的符号;如果您需要更具体的内容(即您的变量中包含其他字符),您需要自己定义它,而不是使用 \w...

      【讨论】:

        【解决方案4】:

        此函数将匹配任何 Python 标识符,将替换任何所需的目标变量,并且所有这些都封装起来易于使用:

        import re
        
        def subst_in(s, varname, keywords={'and', 'or', 'not'}):
            repl = "{} in {{}}".format(varname)
            def fn(match):
                s = match.group(0)
                return s if s in keywords else repl.format(s)
            return re.sub("[a-z_][a-z0-9_]*", fn, s, flags=re.I)
        
        f = "(A or B) and not(A and C)"
        fp = subst_in(f, "x")
        

        给予

        '(x in A or x in B) and not(x in A and x in C)'
        

        编辑:虽然坦率地说应该是

        'x in B or (x in A and x not in C)'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-06
          • 1970-01-01
          • 1970-01-01
          • 2021-12-09
          • 2010-09-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多