Skip to content

Instantly share code, notes, and snippets.

@cou929
Created June 23, 2011 18:01
Show Gist options
  • Save cou929/1043140 to your computer and use it in GitHub Desktop.
Save cou929/1043140 to your computer and use it in GitHub Desktop.
expand pattern and return sequence
#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
ex.py
expand pattern and return sequence.
Kosei Moriyama <cou929@gmail.com>
>>> expand('report_[01-05].pdf')
['report_01.pdf', 'report_02.pdf', 'report_03.pdf', 'report_04.pdf', 'report_05.pdf']
'''
import re
from optparse import OptionParser
re_brackets = re.compile('(.*?)\[([0-9\-!,]+?)\]([^\(\{]*?)$')
re_braces = re.compile('(.*?)\{(.*?)\}([^\(\{]*?)$')
re_range = re.compile('(!)?([0-9]+)(-([0-9]+))?')
def expand(line):
'''
>>> expand('[1-3].jpg')
['1.jpg', '2.jpg', '3.jpg']
>>> expand('[01-03].jpg')
['01.jpg', '02.jpg', '03.jpg']
>>> expand('www.example.{com,co.jp}')
['www.example.com', 'www.example.co.jp']
>>> expand('foo_[001-005,!002-003].txt')
['foo_001.txt', 'foo_004.txt', 'foo_005.txt']
>>> expand('www.foo[01-03].batch.{com,co.jp}')
['www.foo01.batch.com', 'www.foo02.batch.com', 'www.foo03.batch.com', 'www.foo01.batch.co.jp', 'www.foo02.batch.co.jp', 'www.foo03.batch.co.jp']
>>> expand('foobarbaz')
['foobarbaz']
'''
q = [line]
ret = []
while len(q) > 0:
cur = q.pop(0)
# expand []
res_brackets = re_brackets.match(cur)
if res_brackets:
pre, pattern, post = res_brackets.groups()
for token in pattern.split(','):
neg, low, null, high= re_range.match(token).groups()
if not high:
high = low
if len(low) == len(high) and int(low) <= int(high):
format = '{0:0' + str(len(low)) + 'd}'
for i in range(int(low), int(high) + 1):
l = pre + format.format(i) + post
if neg:
q = filter(lambda x: x != l, q)
ret = filter(lambda x: x != l, ret)
else:
q.append(l)
continue
# expand {}
res_braces = re_braces.search(cur)
if res_braces:
pre, pattern, post = res_braces.groups()
map(lambda x: q.append(pre + x + post), pattern.split(','))
continue
# expanded
ret.append(cur)
return ret
if __name__ == "__main__":
parser = OptionParser(usage='%prog PATTERN')
parser.add_option("-t", "--test", action="store_true",
dest="run_doctest", default=False, help="run_doctest")
options, args = parser.parse_args()
if options.run_doctest:
import doctest
doctest.testmod()
elif len(args) <= 0:
parser.print_help()
exit()
else:
for arg in args:
print "\n".join(expand(arg))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment