2016-08-06 20 views
3

Ich bin neu zu erfassen, um mit pyparsing (Python 2.7) und hat ein paar Fragen zu diesem Code:pyparsing einen Text zu entfernen und wie Sie Text mit Leerzeichen

import pyparsing as pp 

openBrace = pp.Suppress(pp.Literal("{")) 
closeBrace = pp.Suppress(pp.Literal("}")) 
ident = pp.Word(pp.alphanums + "_" + ".") 
otherStuff = pp.Suppress(pp.Word(pp.alphanums + "_" + "." + "-" + "+")) 
comment = pp.Literal("//") + pp.restOfLine 
messageName = ident 
messageKw = pp.Suppress("msg") 
messageExpr = pp.Forward() 
messageExpr << (messageKw + messageName + openBrace + 
       pp.Optional(otherStuff) + pp.ZeroOrMore(messageExpr) + 
       pp.Optional(otherStuff) + closeBrace).ignore(comment) 

print messageExpr.parseString("msg msgName1 { msg msgName2 { some text } }") 

Ich verstehe, don `t wirklich, warum es entfernt der Text "msg" im inneren msgName2. Die Ausgabe lautet: [ 'msgName1', 'Name2'] aber ich erwartete: [ 'msgName1', 'msgName2']

Darüber hinaus habe ich frage mich, wie alle anderen Text zu erfassen ("some text") einschließlich Leerzeichen zwischen den Klammern.

Vielen Dank im Voraus

Antwort

4

Ein paar Punkte:

  1. messageKw soll mit der pyparsing Keyword-Klasse definiert werden. Im Moment stimmen Sie nur mit dem Literal "msg" überein, und selbst wenn das der führende Teil von "msgName2" ist, wird es übereinstimmen. Ändern Sie diese an:

    messageKw = pp.Suppress(pp.Keyword("msg")) 
    
  2. otherStuff ein sehr gierig Matcher ist, und wird sogar das führende „msg“ Schlüsselwort übereinstimmen, welche Schrauben Sie Ihre verschachtelten Matching. Alles, was Sie brauchen, ist ein Look-Ahead in otherStuff, um sicherzustellen, dass das, was Sie dabei sind nicht die ‚msg‘ Schlüsselwort übereinstimmen ist:

    otherStuff = ~messageKw + pp.Suppress(pp.Word(pp.alphanums + "_" + "." + "-" + "+")) 
    

ich mit diesen Veränderungen denken, sollten Sie in der Lage zu machen weiteren Fortschritt.

Glückwunsch, BTW, beim Schreiben eines rekursiven Parsers (mit der Forward-Klasse). Dies ist im Allgemeinen ein fortgeschritteneres Parsing-Thema.

+0

Danke für die Hilfe und die Ermutigung. Ich habe eine andere Frage, aber es ist anders, also werde ich eine neue Frage beginnen. – XYZ

2

Ihre erste Abfrage beantworten:

>>> import pyparsing as pp 
>>> 
>>> openBrace = pp.Suppress(pp.Literal("{")) 
>>> closeBrace = pp.Suppress(pp.Literal("}")) 
>>> ident = pp.Word(pp.alphanums + "_" + ".") 
>>> otherStuff = pp.Suppress(pp.Word(pp.alphanums + "_" + "." + "-" + "+")) 
>>> comment = pp.Literal("//") + pp.restOfLine 
>>> messageName = ident 
>>> messageKw = pp.Suppress("msg") 
>>> messageExpr = pp.Forward() 
>>> messageExpr << (messageKw + messageName + openBrace + 
...     pp.ZeroOrMore(messageExpr) + pp.ZeroOrMore(otherStuff) + 
...    closeBrace).ignore(comment) 
Forward: ... 
>>> 
>>> print messageExpr.parseString("msg msgName1 { msg msgName2 { some text } }") 
['msgName1', 'msgName2'] 
+0

Doh! Das funktioniert in diesem speziellen Fall. Aber was, wenn es vor "msg msgName2" noch einen anderen Text geben kann? print messageExpr.parseString ("msg msgName1 {irgendein Text msg msgName2 {irgendein Text}}") Der folgende Code funktioniert nicht: [[code]] messageExpr << (messageKw + nachrichtenName + openBrace + pp.ZeroOrMore (otherStuff) + pp.ZeroOrMore (messageExpr) + pp.ZeroOrMore (otherStuff) + closeBrace) .ignore (Kommentar) – XYZ