【问题标题】:Mapping Boolean formulas to Python set expressions将布尔公式映射到 Python 集合表达式
【发布时间】:2014-03-12 01:58:21
【问题描述】:
假设我有一个使用一组已知标记的布尔公式,例如:
- 布尔运算符:
and、or、not
- 分组运算符:
(、)
给定一个使用这些标记的布尔公式,例如:
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
【解决方案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)'