Votre deuxième question est facile, alors je vais répondre à cette question en premier. Modifier requête pour attribuer des noms de résultats aux différentes expressions:
query = (zipcode("zip") | foo("foo"))
Maintenant, vous pouvez appeler getName() sur le résultat retourné:
print t,"->", results, results.getName()
Giving:
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
Si vous allez Pour utiliser la fonction Fooess ou zipness du résultat pour appeler une autre fonction, vous pouvez le faire au moment de l'analyse en attachant une action d'analyse à vos expressions foo et 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"))
donne maintenant:
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
Pour votre première question, je ne sais pas exactement quel genre de fonction que vous voulez dire. Pyparsing fournit beaucoup plus de classes d'analyse que juste Regex (comme Word, Keyword, Literal, CaselessLiteral), et vous composez votre analyseur en les combinant avec '+', '|', '^', '~', '@' et '*' les opérateurs. Par exemple, si vous voulez analyser un numéro de sécurité sociale des États-Unis, mais pas utiliser une expression régulière, vous pouvez utiliser:
ssn = Combine(Word(nums,exact=3) + '-' +
Word(nums,exact=2) + '-' + Word(nums,exact=4))
correspond à Word pour « mots » contigus composés des caractères donnés dans son constructeur, Unir concatène les jetons correspondants en un seul jeton.
Si vous voulez analyser pour obtenir une liste potentielle de ces chiffres, délimité par l «/des », utilisez:
delimitedList(ssn, '/')
ou s'il y avait entre 1 et 3 de ces chiffres, sans delimters, utilisez:
ssn * (1,3)
et toute expression peut avoir des noms de résultats ou analyser les actions qui leur sont rattachés, pour enrichir davantage les résultats ou la analysables fonctionnalité lors de l'analyse. Vous pouvez même créer des analyseurs récursifs, tels que des listes imbriquées de parenthèses, d'expressions arithmétiques, etc. à l'aide de la classe Forward. Mon intention quand j'ai écrit pyparsing était que cette composition de parseurs à partir des blocs de construction de base serait la forme primaire pour créer un analyseur. Ce n'est que dans une version ultérieure que j'ai ajouté Regex (ce que je pensais être) comme la valve d'échappement ultime - si les gens ne pouvaient pas construire leur analyseur, ils pourraient se rabattre sur le format regex. Ou, comme le suggère une autre affiche, vous pouvez ouvrir la source de pypars et sous-classer l'une des classes existantes, ou écrire la vôtre, en suivant leur structure. Voici une classe qui correspondrait à des caractères jumelés:
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")
Alors que:
punc = r"[email protected]#$%^&*_-+=|\?/"
parser = OneOrMore(Word(alphas) | PairOf(punc))
print parser.parseString("Does ** this match @@@@ %% the parser?")
donne:
['Does', '**', 'this', 'match', '@@', '@@', '%%', 'the', 'parser']
(Notez l'omission du single de fuite '?')
Merci pour cette réponse réfléchie. J'ai littéralement rêvé de ça hier soir. Je pense avoir un exemple pour illustrer ce que j'essaie de faire. L'un des exemples de pyparsing est l'analyse d'une adresse de rue. Et si je voulais étendre ce code pour analyser une ville et un État. Je pourrais analyser l'état en utilisant stateAbbreviation = oneOf ("" "AA AE AK AL ... (comme vous l'avez indiqué) .Mais si je veux analyser une ville en appelant une fonction dans un autre morceau de code, isStringPlacenmae (), ou peut-être un webservice qui me dira si une chaîne donnée est un nom de lieu ... – Art
Quelques informations supplémentaires: J'écris un analyseur pour catégoriser les requêtes de recherche J'espère déterminer si une requête est une adresse, un code postal, un suivi nombre, expression mathématique, etc ... – Art
Une action d'analyse peut être utile pour ajouter une validation au-delà de la simple correspondance d'expression Si l'autre logique échoue, l'action parse déclenche une ParseException, et l'analyseur la traitera comme un échec. l'expression originale. – PaulMcG