Frage

Ich muss eine Datei mit XML -Kommentaren analysieren. Insbesondere handelt es sich um eine AC# -Datei mit der MS /// Konvention.

Daraus müssten ich herausziehen foobar, oder /// foobar wäre auch akzeptabel. (HINWEIS - Dies funktioniert immer noch nicht, wenn Sie das XML in einer Zeile herstellen ...)

testStr = """
    ///<summary>
    /// foobar
    ///</summary>
    """

Hier ist was ich habe:

import pyparsing as pp

_eol = pp.Literal("\n").suppress()
_cPoundOpenXmlComment = Suppress('///<summary>') + pp.SkipTo(_eol)
_cPoundCloseXmlComment = Suppress('///</summary>') + pp.SkipTo(_eol)
_xmlCommentTxt = ~_cPoundCloseXmlComment + pp.SkipTo(_eol)
xmlComment = _cPoundOpenXmlComment + pp.OneOrMore(_xmlCommentTxt) + _cPoundCloseXmlComment

match = xmlComment.scanString(testStr)

und Ausgabe:

for item,start,stop in match:
    for entry in item:
        print(entry)

Aber ich hatte nicht viel Erfolg mit dem Grammer, der in mehrfacher Line arbeitete.

(Hinweis - Ich habe das obige Beispiel in Python 3.2 getestet; es funktioniert, aber (gemäß meinem Problem) druckt keine Werte)

Vielen Dank!

War es hilfreich?

Lösung

Wie wäre es mit Verwendung nestedExpr:

import pyparsing as pp

text = '''\
///<summary>
/// foobar
///</summary>
blah blah
///<summary> /// bar ///</summary>
///<summary>  ///<summary> /// baz  ///</summary> ///</summary>    
'''

comment=pp.nestedExpr("///<summary>","///</summary>")
for match in comment.searchString(text):
    print(match)
    # [['///', 'foobar']]
    # [['///', 'bar']]
    # [[['///', 'baz']]]

Andere Tipps

Ich finde Literal('\n') ist dein Problem. Sie möchten kein wörtliches mit Whitespace -Charakteren bauen (da Literale standardmäßig die Whitespace überspringen, bevor Sie versuchen, übereinzustimmen). Versuchen Sie es zu verwenden LineEnd() stattdessen.

Bearbeiten 1:Nur weil Sie eine unendliche Schleife mit Lineend bekommen, heißt das nicht, dass wörtlich (' n') besser ist. Versuchen Sie hinzu .setDebug() am Ende deines _eol Definition, und Sie werden sehen, dass es nie mit etwas übereinstimmt.

Anstatt zu versuchen, den Körper Ihres Kommentars als "eine oder mehrere Zeilen zu definieren, die keine Schlusslinie sind, sondern alles bis zum Ende der Leitung richten", was ist, wenn Sie es nur tun:

xmlComment = _cPoundOpenXmlComment + pp.SkipTo(_cPoundCloseXmlComment) + _cPoundCloseXmlComment 

(Der Grund, warum Sie eine unendliche Schleife mit LineSend () erhalten haben, war, dass Sie im Wesentlichen OneOrmore (Skipto (Lineend ()) durchgeführt haben, aber nie das Lineend () konsumierten, so dass der OneOrmore einfach passend und passend, analysiert und analysiert und Rückgabe einer leeren Saite seit der Parsingposition war bei das Ende der Linie.)

Sie können einen XML -Parser verwenden, um XML zu analysieren. Es sollte einfach sein, relevante Kommentarzeilen zu extrahieren:

import re
from xml.etree import cElementTree as etree

# extract all /// lines
lines = re.findall(r'^\s*///(.*)', text, re.MULTILINE)

# parse xml
root = etree.fromstring('<root>%s</root>' % ''.join(lines))
print root.findtext('summary')
# -> foobar
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top