OK, so in the spirit of Code-Golf, I\'m trying out something new here: Code-Bowling.
In golf, you try to get the lowest score (smallest application, mos
The asker mentioned regular expressions, so clearly he is looking for an answer using regular expressions. I was baffled after I saw that most of the answers thus far totally fail to realize the power of regular expressions and embrace them.
Thus, my solution. Python code that generates random matches given a regular expression. And the output is totally random, I swear!
import random, time
def parse_regex(regex):
path = [('()', []), ('|', [])]
path[0][1].append(path[1])
i = 0
while i < len(regex):
char = regex[i]
if path[-1][0] in ('[]', '[^]'):
if char == ']' and path[-1][1]:
old2 = path.pop()
assert old2[0] in ('[]', '[^]')
elif char == '-' and len(path[-1][1]) and i+1 < len(regex) and regex[i+1] != ']':
tmp1 = path[-1][1].pop()
assert tmp1[0] is None
tmp1 = tmp1[1]
tmp2 = regex[i+1]
assert ord(tmp2) > ord(tmp1)
for tmp in range(ord(tmp1), ord(tmp2) + 1):
path[-1][1].append((None, chr(tmp)))
i += 1
else:
path[-1][1].append((None, char))
else:
if char == '(':
new1 = ('()', [])
new2 = ('|', [])
new1[1].append(new2)
path[-1][1].append(new1)
path.extend([new1, new2])
elif char == ')':
old2 = path.pop()
old1 = path.pop()
assert old2[0] == '|'
assert old1[0] == '()'
elif char == '|':
new2 = ('|', [])
old2 = path.pop()
assert old2[0] == '|'
path[-1][1].append(new2)
path.append(new2)
elif char == '[':
tmp = '[]'
if i+1 < len(regex) and regex[i+1] == '^':
tmp = '[^]'
i += 1
new = (tmp, [])
path[-1][1].append(new)
path.append(new)
elif char == '.':
path[-1][1].append(('.', None))
elif char in ('*', '+', '?'):
assert len(path[-1][1])
tmp = path[-1][1].pop()
path[-1][1].append((char, tmp))
else:
path[-1][1].append((None, char))
i += 1
assert len(path) == 2
return path[0]
def generate_match(regextree):
match = ''
if regextree[0] == '()':
regextree = random.choice(regextree[1])
match += generate_match(regextree)
elif regextree[0] == '|':
for item in regextree[1]:
match += generate_match(item)
elif regextree[0] == None:
match += regextree[1]
elif regextree[0] == '.':
match += random.choice([chr(i) for i in range(32, 127)])
elif regextree[0] in ('*', '+'):
if regextree[0] == '+':
match += generate_match(regextree[1])
# We favour shorter matches
while True:
if random.choice(['yes', 'yes', 'no']) == 'yes':
match += generate_match(regextree[1])
else:
break
elif regextree[0] == '?':
if random.choice(['yes', 'no']) == 'yes':
match += generate_match(regextree[1])
elif regextree[0] == '[]':
match += random.choice([generate_match(item) for item in regextree[1]])
elif regextree[0] == '[^]':
match += random.choice(list(set(chr(i) for i in range(32, 127)) - set(generate_match(item) for item in regextree[1])))
else:
raise
return match
t1 = time.time()
y, m, d = time.localtime(t1)[:3]
t2 = time.mktime((y, m, d, 0, 0, 0) + time.localtime(t1)[-3:])
t = int(t1 - t2)
# Can't rely on python setting the random seed randomly enough.
# Thus, we seed it with the help of cafebabe and current time.
random.seed((0xcafebabe ^ 0x4eb) + t / 21600)
print generate_match(parse_regex('Good (Morning|Afternoon|Evening|Night)'))