python中的正则表达式以匹配逻辑表达式

时间:2016-01-29 00:20:05

标签: python regex

我在python中寻找一个正则表达式来匹配逻辑表达式。

我想匹配字符串NOT搜索字符串。

我只想匹配逻辑运算符(AND | OR)之间的两个文字,它是由空格分隔的两个不同的单词。

示例:

  

以下条件应符合:

  • (abc AND xyz)
  • (abc AND 123)
  • (abc AND 123.456)
  • (123 AND 123.456)
  • (。001 AND 1)
  

与OR运算符相同

  • (abc OR xyz)
  • (abc OR 123)
  • (abc OR 123.456)
  • (123 OR 123.456)
  • (。001 OR 1)
  

以下条件不匹配:

  • (AND AND AND)
  • (AND AND abc)
  • (123 AND AND)
  • (或或)
  • (AND OR OR)

我尝试了以下但没有任何成功,('AND AND abc')仍然匹配......('abc AND AND')虽然不匹配。

  • ^((?!AND$|OR$)\w+|\d*\.\d+|\d+)\s+(AND|OR)\s+((?!AND$|OR$)\w+|\d*\.\d+|\d+)$

代码:

p=re.compile(r'(^((?!AND$|OR$)\w+|\d*\.\d+|\d+)\s+(AND|OR)\s+((?!AND$|OR$)\w+|\d*\.\d+|\d+)$)')
p.match('AND AND abc')

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

你在那里有很多事情 最好的办法是将顺序操作员检查移到开头 使用先行断言。其余的只是匹配一个表格。

请注意,您还可以在运算符中添加空白边界检查 检查你是否认为ANDxxx可能是一个操作数。

更新 - 通过OP请求,在操作数和操作数之前添加了可选+-和可选的
数学表达前后的空格。

^(?!.*(?<!\S)(?:AND|OR)\s+(?:AND|OR)(?!\S))\s*([+-]?(?:\w+|(?:\d+(?:\.\d*)?|\.\d+)))\s+(AND|OR)\s+([+-]?(?:\w+|(?:\d+(?:\.\d*)?|\.\d+)))\s*$

Expanded

 ^ 
 (?!                      # Lookahead, no sequential operands
      .* 
      (?<! \S )                # WSP boundary
      (?: AND | OR )
      \s+ 
      (?: AND | OR )
      (?! \S )                 # WSP boundary
 )                        # End lookahead

 \s*                      # Optional WSP
 (                        # (1 start), Operand 1
      [+-]?                    # Optional + or -
      (?:
           \w+                      # Words
        |                         # or,
           (?:                      # Decimal number
                \d+ 
                (?: \. \d* )?
             |  \. \d+ 
           )
      )
 )                        # (1 end), Operand 1
 \s+ 
 ( AND | OR )             # (2), Operator AND / OR
 \s+ 
 (                        # (3 start), Operand 2
      [+-]?                    # Optional + or -
      (?:
           \w+                      # Words
        |                         # or,
           (?:                      # Decimal number
                \d+ 
                (?: \. \d* )?
             |  \. \d+ 
           )
      )
 )                        # (3 end), Operand 2
 \s*                      # Optional WSP
 $ 

输入测试

  abc AND -xyz  

输出

 **  Grp 0 -  ( pos 0 , len 16 ) 
  abc AND -xyz  
 **  Grp 1 -  ( pos 2 , len 3 ) 
abc
 **  Grp 2 -  ( pos 6 , len 3 ) 
AND
 **  Grp 3 -  ( pos 10 , len 4 ) 
-xyz

答案 1 :(得分:0)

我煮了一个,希望这会有所帮助:

'^\((?!(AND|OR)\s)[^\s]+\s+(AND|OR)\s+(?!(AND|OR)\s*\))[^\s]+\)$'

演示(expressions是您的测试字符串列表):

>>> def trymatch(expressions, regex):
...     for e in expressions:
...         if re.search(regex, e):
...             print('matched ' + e)
...         else:
...             print('did not match ' + e)
... 
>>> 
>>> regex = '^\((?!(AND|OR)\s)[^\s]+\s+(AND|OR)\s+(?!(AND|OR)\s*\))[^\s]+\)$'
>>> trymatch(expressions, regex)
matched (abc AND xyz)
matched (abc AND 123)
matched (abc AND 123.456)
matched (123 AND 123.456)
matched (.001 AND 1)
matched (abc OR xyz)
matched (abc OR 123)
matched (abc OR 123.456)
matched (123 OR 123.456)
matched (.001 OR 1)
did not match (AND AND AND)
did not match (AND AND abc)
did not match (123 AND AND)
did not match (OR AND OR)
did not match (AND OR OR)

答案 2 :(得分:-1)

根据comment57872651,如果你想匹配任何级别的嵌套表达式,那么使用正则表达式是不可能的:regular expressions cannot match recursive structures

如果你只想匹配单个表达式(a <op> b / <op> a),那么正则表达式很好,the other answer就是一个例子。

然而,嵌套的案例可以由Perl的扩展模式处理 - 这些不是在数学意义上的正则表达式,而是正式的语法定义。以上链接也有这样的例子。