Make an application that displays text at random that conforms to the specified regex

后端 未结 11 844
情书的邮戳
情书的邮戳 2021-01-30 05:39

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

11条回答
  •  庸人自扰
    2021-01-30 05:56

    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)'))
    

提交回复
热议问题