2 番目の質問は簡単なので、最初にお答えします。クエリを変更して、結果の名前をさまざまな式に割り当てます。
query = ( zipcode("zip") | foo("foo") )
これで、返された結果に対して getName() を呼び出すことができます。
print t,"->", results, results.getName()
与える:
80517 -> ['80517'] zip
Expected Re:('\\d{5}(?:[-\\s]\\d{4})?') (at char 0), (line:1, col:1)
90001-3234 -> ['90001-3234'] zip
! sfs -> ['! sfs'] foo
結果の fooness または zipness を使用して別の関数を呼び出す場合は、解析アクションを foo および zipcode 式に添付することにより、解析時にこれを行うことができます。
# enclose zipcodes in '*'s, foos in '#'s
zipcode.setParseAction(lambda t: '*' + t[0] + '*')
foo.setParseAction(lambda t: '#' + t[0] + '#')
query = ( zipcode("zip") | foo("foo") )
今与えます:
80517 -> ['*80517*'] zip
Expected Re:('\\d{5}(?:[-\\s]\\d{4})?') (at char 0), (line:1, col:1)
90001-3234 -> ['*90001-3234*'] zip
! sfs -> ['#! sfs#'] foo
最初の質問については、どのような機能を意味するのか正確にはわかりません。Pyparsing は、正規表現 (Word、Keyword、Literal、CaselessLiteral など) よりも多くの解析クラスを提供し、それらを '+'、'|'、'^'、'~'、'@' および「*」演算子。たとえば、米国の社会保障番号を解析したいが、正規表現を使用したくない場合は、次を使用できます。
ssn = Combine(Word(nums,exact=3) + '-' +
Word(nums,exact=2) + '-' + Word(nums,exact=4))
コンストラクター内の指定された文字で構成される連続した「単語」の単語が一致し、Combine は一致したトークンを単一のトークンに連結します。
'/' で区切られたそのような番号の潜在的なリストを解析したい場合は、次を使用します。
delimitedList(ssn, '/')
または、そのような数字が 1 ~ 3 個あり、区切り文字がない場合は、次を使用します。
ssn * (1,3)
また、任意の式に結果名または解析アクションを関連付けて、解析結果または解析中の機能をさらに充実させることができます。Forward クラスを使用して、ネストされた括弧のリスト、算術式などの再帰パーサーを構築することもできます。
私が pyparsing を書いたときの私の意図は、基本的なビルディング ブロックからのパーサーのこの構成が、パーサーを作成するための主要な形式になるということでした。正規表現を究極の逃避弁として追加したのは、後のリリースになってからです (私がそうだったと思っていたもの)。人々がパーサーを構築できなかった場合、正規表現の形式に頼ることができました。
または、別のポスターが示唆しているように、pyparsing ソースを開き、既存のクラスの 1 つをサブクラス化するか、構造に従って独自のクラスを作成することができます。ペア文字に一致するクラスは次のとおりです。
class PairOf(Token):
"""Token for matching words composed of a pair
of characters in a given set.
"""
def __init__( self, chars ):
super(PairOf,self).__init__()
self.pair_chars = set(chars)
def parseImpl( self, instring, loc, doActions=True ):
if (loc < len(instring)-1 and
instring[loc] in self.pair_chars and
instring[loc+1] == instring[loc]):
return loc+2, instring[loc:loc+2]
else:
raise ParseException(instring, loc, "Not at a pair of characters")
となることによって:
punc = r"~!@#$%^&*_-+=|\?/"
parser = OneOrMore(Word(alphas) | PairOf(punc))
print parser.parseString("Does ** this match @@@@ %% the parser?")
与えます:
['Does', '**', 'this', 'match', '@@', '@@', '%%', 'the', 'parser']
(末尾のシングル '?' の省略に注意してください)