String generator based on a wildcard

2

0

Your task, if you accept it, is to make a string generator that generates strings based on a wildcard.

You can make a function or a full program that receives 1 argument and sends to the standard output/console a string that matches.

Wildcard characters and sequences:

  • * produces 0 or more random characters
  • ? produces exactly 1 random character
  • [] detonates a group and produces any one of the characters from the group, exactly once.
  • []* produces at least 0 of the characters from that group
  • []? produces any one of the characters from that group, at most once
  • []{n} produces n characters in that group
  • Anything else is a literal string

The supported characters to return are a-z, A-Z and 0-9.
Casing doesn't matter.

You can do whatever you want with invalid input.

Examples:

f('a[d-f]{3}') //return 'addd', 'adde', 'addf' ...

f('a*') //returns 'a' or anything starting with 'a'

f('[bt]est') //returns 'best', 'test'

Scoring:

  • Shortest code in bytes wins.
  • -10% bonus if you support symbols
  • -10% bonus if you implement multiple matches, inside each group (e.g.: [ae,c-d,0-5])
  • -20% bonus if you implement negated group (e.g.: [^a-f] returns anything that doesn't start with a-f)
  • -10% if you support at least 3 regex character classes (e.g.: \d,\s,\D)
  • Standard loopholes are not allowed!

Any doubts, feel free to ask in a comment.

Ismael Miguel

Posted 2014-12-26T17:45:13.083

Reputation: 6 797

Question was closed 2014-12-26T20:41:16.963

Can groups be nested? ("a[[d-f]?g]*") – BMac – 2014-12-26T18:06:21.080

@BMac No, that would be too complicated to parse. I wanted to keep this as simple as possible, but I already over-complicated it. You can implement it (since it is considered invalid output, you do what you want) if you want. But it won't have any benefit for you. Unless people upvote your answer for implementing on that way, then you would get reputation. – Ismael Miguel – 2014-12-26T18:08:50.770

Answers

1

Python 3, 511 bytes - 10% = 459.9

It's early morning over here so golfing mode hasn't quite kicked into my system yet, but it was a really fun-looking problem so I thought I'd try it anyway.

from random import*
C=0
r=input()
i=0
S=""
Q=""
while i<len(r):
 c=r[i]
 if i<len(r)-1:d=r[i+1]
 if"]"==c:
  C=0
  if d not in"*?{":S+=choice(Q)
 elif"["==c:C=1;Q=""
 elif"*"==c:
  while random()>.2:S+=choice(Q)
 elif"?"==c:S+=choice(Q)*randint(0,1)
 elif"{"==c:
  a=""
  while r[i+1]!="}":a+=r[i+1];i+=1
  S+="".join(choice(Q)for _ in range(int(a)))
 elif"}"!=c:
  if"-"==d:Q+="".join(chr(x)for x in range(ord(c),ord(r[i+2])+1));i+=2
  else:
   Q=C*Q+c
   if not C and d not in"*?{":S+=choice(Q)
 i+=1
print(S)

I'm claiming the "multiple matches, inside each group" bonus. You can try it out like so:

[abA-C0]*

Sp3000

Posted 2014-12-26T17:45:13.083

Reputation: 58 729

Your code looks nice! The negated group should be trivial to implement. Same for the classes. But be careful with the classes, since they have to always return valid results. – Ismael Miguel – 2014-12-26T18:54:37.160