Question

Je dois analyser un fichier contenant des commentaires xml. Plus précisément, il est un fichier c # en utilisant la convention MS ///.

A partir de ce que je avais besoin de sortir foobar ou /// foobar seraient trop acceptables,. (Note - cela ne fonctionne toujours pas si vous faites tout le xml sur une seule ligne ...)

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

Voici ce que j'ai:

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)

et pour délivrer en sortie:

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

Mais je n'ai pas eu beaucoup de succès avec le Grammer travaillant sur plusieurs lignes.

(note - je l'ai testé l'exemple ci-dessus en python 3.2, il fonctionne, mais (par mon problème) n'imprime pas de valeurs)

Merci!

Était-ce utile?

La solution

Comment l'utilisation 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']]]

Autres conseils

Je pense que Literal('\n') est votre problème. Vous ne voulez pas construire un littérales avec des caractères blancs (depuis littéraux par défaut sauter les espaces avant d'essayer de correspondre). Essayez d'utiliser à la place LineEnd().

EDIT 1: Tout simplement parce que vous obtenez une boucle infinie avec LineEnd ne signifie pas que littérales ( « \ n ») est mieux. Essayez d'ajouter .setDebug() à la fin de la définition de votre _eol, et vous verrez qu'il ne correspond jamais à quoi que ce soit.

Au lieu d'essayer de définir le corps de votre commentaire comme « une ou plusieurs lignes qui ne sont pas une ligne de clôture, mais obtenir tout jusqu'à la fin de ligne », si vous faites juste:

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

(La raison pour laquelle vous obtenez une boucle infinie avec LineEnd () était que vous étiez essentiellement en train de faire OneOrMore (skipTo (LineEnd ())), mais jamais consommer la LineEnd (), de sorte que le OneOrMore juste gardé correspondant et la correspondance et la correspondance , l'analyse syntaxique et retourner une chaîne vide depuis la position de l'analyse syntaxique était à la fin de la ligne.)

Vous pouvez utiliser un analyseur XML pour analyser xml. Il devrait être facile d'extraire des lignes de commentaires pertinents:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top