add the --group argument

This commit is contained in:
Johann Dreo 2014-09-23 09:18:14 +02:00
commit 49e8b76c2d
2 changed files with 64 additions and 21 deletions

View file

@ -16,7 +16,7 @@ def run( cmd, text, nowait=False ):
# If there is a string formatting mark
try:
# put the matching text in it
behest = cmd % text
behest = cmd % tuple(text)
except TypeError:
# else, do not
behest = cmd
@ -35,7 +35,7 @@ def call( cmd, text, nowait=False, queue=None ):
run( cmd, text, nowait )
def parse( text, pattern, cmd=[""], nowait=False, queue=None ):
def parse( text, pattern, cmd=[""], nowait=False, queue=None, capture_groups = False ):
regex = re.compile(pattern)
for match in regex.finditer(text):
@ -47,18 +47,29 @@ def parse( text, pattern, cmd=[""], nowait=False, queue=None ):
else:
nb_groups = len(match.groups())
# Build a list of colors that match the number of grouped,
# If there is not enough commands, duplicate the last one.
group_cmds = cmd + [cmd[-1]] * (nb_groups - len(cmd))
if capture_groups:
# For each group index.
# Note that match.groups returns a tuple (thus being indexed in [0,n[),
# but that match.start(0) refers to the whole match, the groups being indexed in [1,n].
# Thus, we need to range in [1,n+1[.
texts = []
for group in range(1, nb_groups+1):
# If a group didn't match, there's nothing to do
if match.group(group) is not None:
texts.append( text[match.start(group):match.end(group)] )
# For each group index.
# Note that match.groups returns a tuple (thus being indexed in [0,n[),
# but that match.start(0) refers to the whole match, the groups being indexed in [1,n].
# Thus, we need to range in [1,n+1[.
for group in range(1, nb_groups+1):
# If a group didn't match, there's nothing to do
if match.group(group) is not None:
call( group_cmds[group-1], text[match.start(group):match.end(group)], nowait, queue )
# Finally, call a single command with all the captured groups
call( cmd[0], texts, nowait, queue )
else:
# Build a list of commands that match the number of groups,
# If there is not enough commands, duplicate the last one.
group_cmds = cmd + [cmd[-1]] * (nb_groups - len(cmd))
for group in range(1, nb_groups+1):
# If a group didn't match, there's nothing to do
if match.group(group) is not None:
call( group_cmds[group-1], text[match.start(group):match.end(group)], nowait, queue )
def write( text, stream = sys.stdout):
@ -77,7 +88,7 @@ def write( text, stream = sys.stdout):
pass
def read_parse( stream_in, stream_out, pattern, cmd, nowait = False, at_end = False ):
def read_parse( stream_in, stream_out, pattern, cmd, nowait = False, at_end = False, capture_groups = False ):
"""
Read the given file-like object as a non-blocking stream
and call the function on each item (line),
@ -107,7 +118,7 @@ def read_parse( stream_in, stream_out, pattern, cmd, nowait = False, at_end = Fa
# Write the line being processed
write( item, stream_out )
# Then do something
parse(item, pattern, cmd, nowait, events)
parse(item, pattern, cmd, nowait, events, capture_groups)
if at_end:
while events.not_empty:
@ -140,7 +151,11 @@ if __name__ == "__main__":
parser.add_argument("-e", "--end", action="store_true",
help="Run commands at the end of the input stream.")
parser.add_argument("-g", "--groups", action="store_true",
help="Capture groups as arguments for the CMD, instead of running CMD for each group.\
CMD must have as many formating placeholder as captured groups.")
args = parser.parse_args()
read_parse( sys.stdin, sys.stdout, args.pattern[0], args.commands, args.no_wait, args.end )
read_parse( sys.stdin, sys.stdout, args.pattern[0], args.commands, args.no_wait, args.end, args.groups )