4

xmlコメントを含むファイルを解析する必要があります。///具体的には、MSコンベンションを使用したac#ファイルです。

これから私は引き抜く必要があるfoobarか、あるいは/// foobar受け入れられるでしょう。(注-xmlをすべて1行にすると、これはまだ機能しません...)

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

これが私が持っているものです:

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)

および出力するには:

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

しかし、私は文法が複数行にわたって機能することにあまり成功していません。

(注-上記のサンプルをPython 3.2でテストしました。動作しますが、(私の問題では)値を出力しません)

ありがとう!

4

3 に答える 3

3

Literal('\n')はあなたの問題だと思います。空白文字を使用してリテラルを作成する必要はありません(リテラルはデフォルトで空白をスキップしてから照合を試みるため)。LineEnd()代わりに使用してみてください。

編集1: LineEndで無限ループが発生したからといって、Literal('\ n')が優れているとは限りません。.setDebug()定義の最後に追加してみてください_eol。そうすれば、それが何にも一致しないことがわかります。

コメントの本文を「終了行ではないが、すべてを行末まで取得する1つ以上の行」として定義しようとする代わりに、次のようにするとどうなりますか。

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

(LineEnd()で無限ループが発生した理由は、基本的にOneOrMore(SkipTo(LineEnd()))を実行していましたが、LineEnd()を消費しなかったため、OneOrMoreは一致と一致、一致、解析、および解析位置が行末にあったため、空の文字列を返します。

于 2011-10-19T19:02:38.847 に答える
2

使ってみませんか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']]]
于 2011-10-19T19:51:42.337 に答える
1

xmlパーサーを使用してxmlを解析できます。関連するコメント行を簡単に抽出できるはずです。

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
于 2011-10-19T22:51:10.553 に答える