Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 解析逻辑表达式_Python_String_Parsing_Boolean Logic_Boolean Expression - Fatal编程技术网

Python 解析逻辑表达式

Python 解析逻辑表达式,python,string,parsing,boolean-logic,boolean-expression,Python,String,Parsing,Boolean Logic,Boolean Expression,我有一个任务,我必须根据用户指定的逻辑表达式过滤数据帧。现在,我看到了一个名为PyParser或LARK的模块,我想使用它,但我似乎不知道如何设置它们 我有几个操作符,如CONTAINS,EQUAL,FUZZY\u MATCH等。此外,我还想将一些表达式组合成更复杂的表达式 示例表达式: 列A包含[1,2,3]和(列B模糊匹配'bla'或列C等于45) 因此,我希望有一些结构化的Dict或List,按照如何执行它们的顺序列出操作的级别。因此,此示例表达式的预期结果如下所示: [['ColumnA

我有一个任务,我必须根据用户指定的逻辑表达式过滤数据帧。现在,我看到了一个名为PyParser或LARK的模块,我想使用它,但我似乎不知道如何设置它们

我有几个操作符,如
CONTAINS
EQUAL
FUZZY\u MATCH
等。此外,我还想将一些表达式组合成更复杂的表达式

示例表达式:

列A包含[1,2,3]和(列B模糊匹配'bla'或列C等于45)

因此,我希望有一些结构化的Dict或List,按照如何执行它们的顺序列出操作的级别。因此,此示例表达式的预期结果如下所示:

[['ColumnA', 'CONTAINS', '[1, 2, 3]'], 'AND', [['ColumnB', 'FUZZY_MATCH', 'bla'], OR, ['ColumnC', 'EQUAL', '45']]]
或以书面形式:

{
  'EXPR1': {
    'col': 'ColumnA', 
    'oper': 'CONTAINS', 
    'value': '[1, 2, 3]']
  },
  'OPERATOR': 'AND', 
  'EXPR2': {
    'EXPR21': {
      'col': 'ColumnB', 
      'oper': 'FUZZY_MATCH', 
      'value': 'bla'
    }, 
    'OPERATOR': OR, 
    'EXPR22': {
      'col': 'ColumnC', 
      'oper': 'EQUAL', 
      'value': '45'
    }
  }
}
或者类似的。如果你有更好的方法来构建结果,我愿意听取建议。我对这一点很陌生,所以我相当肯定这一点可以改进。

有趣的问题:)

似乎是该算法的一个相对简单的应用。
我写了一些代码来解析表达式,比如
“((20-10)*(30-20)/10+10)*2”

重新导入
def标记化(str):
返回re.findall(“[+/*()-]”|\d+”,表达式)
def是_编号(str):
尝试:
智力(str)
返回真值
除值错误外:
返回错误
def peek(堆栈):
如果没有堆栈,则返回堆栈[-1]
def应用_运算符(运算符、值):
operator=operators.pop()
right=values.pop()
left=values.pop()
values.append(eval({0}{1}{2}).format(左,运算符,右)))
def优先级更高(op1、op2):
先例={“+”:0,“-”:0,“*”:1,“/”:1}
返回先例[op1]>先例[op2]
def求值(表达式):
标记=标记化(表达式)
值=[]
运算符=[]
对于令牌中的令牌:
如果是_编号(令牌):
values.append(int(令牌))
elif令牌==“(”:
operators.append(令牌)
elif标记==”):
top=peek(操作员)
而top不是None和top!="(":
应用_运算符(运算符、值)
top=peek(操作员)
operators.pop()#丢弃'('
其他:
#接线员
top=peek(操作员)
而top不是None和top!=”(“且优先级更高(top,标记):
应用_运算符(运算符、值)
top=peek(操作员)
operators.append(令牌)
虽然peek(操作员)不是无:
应用_运算符(运算符、值)
返回值[0]
def main():
表达式=“((20-10)*(30-20)/10+10)*2”
打印(计算(表达式))
如果名称=“\uuuuu main\uuuuuuuu”:
main()
我认为我们可以稍微修改代码,使其适用于您的案例:

  • 我们需要修改在
    tokenize()
    中标记输入字符串的方式
    基本上,如果字符串
    ColumnA包含[1,2,3]和(ColumnB FUZZY_MATCH'bla'或ColumnC EQUAL 45)
    ,我们需要一个标记列表:
    ['ColumnA'、'CONTAINS'、'[1,2,3]、'AND'、'('、'ColumnB'、'FUZZY_MATCH'、'bla'、'或''ColumnC'、'EQUAL'、'45'、')]

    这在很大程度上取决于输入字符串的复杂程度,并且需要一些字符串处理,但它相当简单,我将把这留给您
  • 修改
    is_number()
    函数,以检测诸如
    ColumnA
    [1,2,3]
    等内容。
    基本上,除了谓词
    之外的所有内容都包含
    /
    模糊匹配
    /
    相等
    、运算符
    /
    以及偏执词
    /
  • 如果
    op1
    ['CONTAINS'、'EQUAL'、…]
    op2
    ['and'、'OR']之间,则修改
    更高的优先级(op1、op2)
    以返回true

    这是因为我们希望
    包含
    等于
    总是在
    /
    之前进行计算
  • 修改
    apply_运算符(运算符,值)
    以实现如何计算布尔表达式
    ColumnA包含[1,2,3]
    或表达式
    true和false的逻辑
    请记住,
    包含
    /
    模糊匹配
    /
    相等
    /
    /
    等都是这里的运算符。
    可能你需要在这里写很多if-else的例子,因为这里可能有很多不同的操作符

  • 好的,谢谢你冗长完整的回答:)看起来这就是我要找的。我会在接下来的几天里测试它。当然。别忘了接受答案,如果它有效的话就结束这个问题;)我知道你已经得到了答案,但是如果你对使用Lark的解决方案感兴趣,请告诉我。