importre# Gonna be using this a lot, so compile it.digit_pattern=re.compile('[0-9]')# We're creating a class because there's a little bit of state to maintain.classOracleErrorFinder(object):def__init__(self,input_file):self.input_file=input_file# This seems weird, but there's a good reason.# When we get to the end of a match, we're going to have already consumed# the next character from the file. So we need to save it for the next round.next_char=Nonedeffind_next_match(self):# Possible states are# '': We haven't found any portion of the pattern yet.# 'O': We found an O# 'R': We found an OR# 'A': We found an ORA# '-': We found an ORA-# 'num1': We found ORA-[0-9]# 'num2': We found ORA-[0-9][0-9]# 'num3': We found ORA-[0-9][0-9][0-9]# 'num4': We found ORA-[0-9][0-9][0-9][0-9]# 'num5': We found ORA-[0-9][0-9][0-9][0-9][0-9], and we're donecurrent_state=''match_so_far=''done=Falsewhilenotdone:ifself.next_char:# If we have a leftover char from last time,# start with that and clear it.c=self.next_charself.next_char=Noneelse:c=self.input_file.read(1)if''==c:match_so_far=Nonedone=True# End of stream and we didn't find a match. Time to stop.elif''==current_stateand'O'==c:# We found the start of what we're looking for.# We don't know if it's the whole thing,# so we just save it and go to the next character.current_state='O'match_so_far='O'elif'O'==current_stateand'R'==c:# We already have an O and now we found the next character!current_state='R'match_so_far+=celif'R'==current_stateand'A'==c:current_state='A'match_so_far+=celif'A'==current_stateand'-'==c:current_state='-'match_so_far+=celif'-'==current_stateanddigit_pattern.match(c):current_state='num1'match_so_far+=celif'num1'==current_state:ifdigit_pattern.match(c):current_state='num2'match_so_far+=celse:# We found a full match,# but not more numbers past the last one.# Time to return what we found.done=Trueelif'num2'==current_state:ifdigit_pattern.match(c):current_state='num3'match_so_far+=celse:# We found a full match,# but not more numbers past the last one.# Time to return what we found.done=Trueelif'num3'==current_state:ifdigit_pattern.match(c):current_state='num4'match_so_far+=celse:# We found a full match,# but not more numbers past the last one.# Time to return what we found.done=Trueelif'num4'==current_state:ifdigit_pattern.match(c):current_state='num5'match_so_far+=celse:# We found a full match,# but not more numbers past the last one.# Time to return what we found.done=Trueelif'num5'==current_state:# We're done for sure!# Note that we read the next character from the file.# Important for code after the loop.done=Trueelse:# We didn't find the next character we wanted.if'O'==c:# We didn't find a full match, but this starts# a new one.current_state='O'match_so_far='O'else:# This character doesn't match our pattern.# It could be a character that's in the wrong place# (such as the - in OR-) or a character that just# doesn't appear in the pattern at all (like X).# We might be in the middle of a partial# match, so throw everything found so far away# and keep going.current_state=''match_so_far=''# Save next char already consumed from file stream.# Could be empty string if we consumed the whole file,# but that's fine.self.next_char=creturnmatch_so_farwithopen(filename)asf:finder=OracleErrorFinder(f)whileTrue:match=finder.find_next_match()ifNoneismatch:break# Print, send to file, add to list, what have you
python 正则 边界_正则表达式匹配记录边界
最新推荐文章于 2022-05-05 21:22:32 发布