好吧,這是矯枉過正,但你會發現很有趣;-)
import collections
import re
def makeMatcher(regex):
reg = re.compile(regex).match
def matcher(s):
match = reg(s)
return match and match.groups() # return None or tuple of match-values
return matcher
class StatefulIter(collections.Iterator):
def __init__(self, seq, stateVars, *transitions, **kwargs):
"""
StatefulIter crunches input sequence using transition rules
:seq :input sequence of data to operate on
:stateVars :state variables to operate on - dict OR space-separated string OR collection of strings
:*transitions :list of (isMatch, onMatch) tuples
(isMatch can be a function or a regex string)
isMatch(data) returns matched fields or None
onMatch(statedict, *fields) processes matched fields, returns isOutput
:**outfn :if isOutput, return outfn(statedict)
"""
outfn = kwargs.pop('outfn')
super(StatefulIter,self).__init__(**kwargs)
self.seq = seq
if isinstance(stateVars, dict):
self.statedict = stateVars
else:
if isinstance(stateVars, basestring):
stateVars = stateVars.split()
self.statedict = {s:None for s in stateVars}
self.trans = [(isMatch if callable(isMatch) else makeMatcher(isMatch), onMatch) for isMatch,onMatch in transitions]
self.outfn = outfn
def next(self):
_sd = self.statedict
while True:
data = self.seq.next()
for isMatch,onMatch in self.trans:
match = isMatch(data)
if match is not None:
res = onMatch(_sd,*match)
if res:
return self.outfn(_sd)
else:
break
class CriteriaIter(StatefulIter):
states = 'person criteria date'
isPeople = r'\((.+)\):'
@staticmethod
def onPeople(statedict, pers):
statedict['person'] = pers
return False
isCriteria = r'\s*<(.*?)>\s*<(.*?)>'
@staticmethod
def onCriteria(statedict, crit, date):
statedict['criteria'] = crit
statedict['date'] = date
return True
@staticmethod
def outfn(statedict):
return statedict['person'], statedict['criteria'], statedict['date']
def __init__(self, seq, outfn=None):
people = (CriteriaIter.isPeople, CriteriaIter.onPeople)
criteria = (CriteriaIter.isCriteria, CriteriaIter.onCriteria)
outfn = outfn or CriteriaIter.outfn
super(CriteriaIter,self).__init__(seq, CriteriaIter.states, people, criteria, outfn=outfn)
class CriteriaFile(file):
def __iter__(self):
return CriteriaIter(self)
def main():
with CriteriaFile('data.txt') as inf:
allEntries = [entry for entry in inf]
allCriteria = set(entry[1] for entry in allEntries)
if __name__=="__main__":
main()
你沒完成你的問題 – vartec 2011-03-21 13:30:13
比較容易回答,如果你真的問一個問題...;) – Nico 2011-03-21 13:30:28
Python已經字典,如果你需要字符串索引 – lunixbochs 2011-03-21 13:36:09