1

次の形式の文字列を変換する必要があります。

'a==1&&(b==2||(c==3||d==4&&e==5)&&f==6)||(g==7&&h==8)'

フィルター処理される sqlalchemy ロジックに ( および を介しor_and_)。最初のステップは、実際に文字列を有用なものに解析することです。私はそれをフォームに入れたいです:

['a==1','&&',['b==2','||',['c==3','||','d==4','&&','e==5'],'&&','f==6'],'||',['g==7','&&','h==8']]

次に、再帰的にステップスルーして解析します。残念ながら、これまで pyparsing を使用したことがないため、この解析ステップで問題が発生しています。

編集(解決策)

interblag上または上で簡単な解決策を見つけることができませんでしたsoが、ドキュメントをかなり掘り下げた後、次の簡単な式をまとめることができました。

from pyparsing import Word, alphanums, nestedExpr

content  = Word( alphanums + '=' ) | '||' | '&&'
unnester = nestedExpr( content = content )

a = 'a==3||b==1&&(c==4||(d==1||e==5)&&f==9)'
unnester.parseString( '(' + a + ')' ).asList()

反復中に平坦化ステップが実行される限り、これはかなりうまくいくようです。

4

2 に答える 2

1

Pyparsing には、演算子の優先順位の認識を含む、括弧でグループ化された操作を解析するためのビルトインinfixNotation(以前はと呼ばれていましたoperatorPrecedence) があります。サンプル式を解析するために、このサンプル コードでどのように使用されているかを確認してください。

from pyparsing import Word, alphas, nums, oneOf, Group, infixNotation, opAssoc

sample = 'a==1&&(b==2||(c==3||d==4&&e==5)&&f==6)||(g==7&&h==8)'

# define some basic elements
varname = Word(alphas)
integer = Word(nums).setParseAction(lambda t:int(t[0]))

# Use varname and integer to define a comparison expression
comparisonOp = oneOf("< == > <= >= !=")
term = varname | integer
comparisonExpr = Group(term + comparisonOp + term)

# Use pyparsing builtin 'infixNotation' to implement parser for
# parenthetically grouped expression of various operators (formerly
# named 'operatorPrecedence')
logicalExpr = infixNotation(comparisonExpr,
    [
    ('&&', 2, opAssoc.LEFT),
    ('||', 2, opAssoc.LEFT),
    ])

# parse out your sample expression, use pprint to do some pretty-printing
import pprint
pprint.pprint(logicalExpr.parseString(sample).asList())

版画:

[[[['a', '==', 1],
   '&&',
   [['b', '==', 2],
    '||',
    [[['c', '==', 3], '||', [['d', '==', 4], '&&', ['e', '==', 5]]],
     '&&',
     ['f', '==', 6]]]],
  '||',
  [['g', '==', 7], '&&', ['h', '==', 8]]]]
于 2013-04-24T13:44:54.313 に答える