Skip to content Skip to sidebar Skip to footer

Parse And Group Multiple Items Together Using Pyparse

This is a build up on Build a simple parser that is able to parse different date formats using PyParse I have a parser that should group one or more users together into a list So a

Solution 1:

You are on the right track, see the embedded comments in this update to your parser:

from pyparsing import *

keywords = ["select", "show", "team", "from", "to", "commits", "and", "or"]
[select, show, team, _from, _to,  commits, _and, _or] = [ CaselessKeyword(word) for word in keywords ]

# define an expression to prevent matching keywords asuser names - used below in users expression
keyword = MatchFirst(map(CaselessKeyword, keywords))

user= Word(alphas+"."+alphas)  # ??? what are you trying todefine here?
user2 = Combine(user+ "'s")
# must not confuse keywords likecommitwith usernames -and use ungroup to 
# unpack single-element token lists
users = ungroup(~keyword + (user|user2))

#~ bnf = (show|select)+Group(users).setResultsName("users")+Optional(team)+(commits).setResultsName("stats") \
    #~+ Optional(_from + quotedString.setParseAction(removeQuotes)('from') +
                    #~ _to + quotedString.setParseAction(removeQuotes)('to'))

def convertToDatetime(tokens):
    # change this code to do your additional parsing/conversion to a Python datetime
    return tokens[0] 
timestamp= quotedString.setParseAction(removeQuotes, convertToDatetime)

# similarto your expression
# - use delimitedList instead of OneOrMore to handle comma-separated list of items
# -add distinction of "xxx team" vs "xxx"
# - dropped expr.setResultsName("name") in favor of short notation expr("name")
# - results names withtrailing'*' will accumulate like elements into a single
#   named result (short notation for setResultsName(name, listAllValues=True) )
# - dropped setResultsName("stats") on keyword "commits", no point to this, commits must always be present
#
bnf = ((show|select)("command") + delimitedList(users("team*") + team | users("user*")) + commits + 
            Optional(_from +timestamp('from') + _to +timestamp('to')))

test ='show abc, def team, xyz commits from "Jan 10,2015" to "27/1/2015"'

print bnf.parseString(test).dump()

Prints:

['show', 'abc', 'def', 'team', 'xyz', 'commits', 'from', 'Jan 10,2015', 'to', '27/1/2015']-command: show-from: Jan10,2015-team: ['def']-to: 27/1/2015-user: ['abc', 'xyz']

Post a Comment for "Parse And Group Multiple Items Together Using Pyparse"