3
\$\begingroup\$

The idea here is to write a little segment that will spit out regular expression patterns when given a string that matches them.

As you might have guessed, this will be a popularity contest, and I'll accept whichever answer has the most upvotes by March 7th

pseudocode Example:

print(reverseRegex('dog')); 
//prints /[a-z]{3}/, /dog/, and a bunch other stuff

EDIT: The regular expressions spat out should not exceed 3 times the input string's length

\$\endgroup\$
  • 3
    \$\begingroup\$ I think the spec could do with tightening. There are countably infinitely many families of countably infinitely many regexes which match any given string. \$\endgroup\$ – Peter Taylor Feb 23 '14 at 17:24
  • \$\begingroup\$ What if the input string is longer than 30 chars? \$\endgroup\$ – Doorknob Feb 23 '14 at 18:10
  • \$\begingroup\$ @doorknob good point, will revise again \$\endgroup\$ – user70585 Feb 23 '14 at 18:11
  • \$\begingroup\$ Now your sample output violates your own rules. \$\endgroup\$ – Doorknob Feb 23 '14 at 18:15
  • 1
    \$\begingroup\$ Maybe in the sandbox: meta.codegolf.stackexchange.com/questions/954/… \$\endgroup\$ – user10766 Feb 23 '14 at 19:17
1
\$\begingroup\$

Ruby

def esc chr
  '\\[]'.index(chr) ? "\\#{chr}" : chr
end

def reverse_regex str
  ords = str.chars.to_a.uniq.map(&:ord).sort
  prev = ords.first
  ranges = ords.slice_before{|x|
    prev, prev2 = x, prev
    prev2 + 1 != x
  }.map{|x| x[0]..x[-1]}

  reversed = "[#{ranges.map{|c|esc(c.min.chr) + (c.min == c.max ? '' : (c.min + 1 == c.max ? '' : '-') + esc(c.max.chr))}*''}]{#{str.size}}"
  reversed.size > str.size * 3 ? /#{Regexp.escape str}/ : /#{reversed}/
end

Sample outputs:

reverse_regex 'dogs are delicious'
  => /[ ac-egilorsu]{18}/
reverse_regex 'a'
  => /a/
reverse_regex ''
  => //
reverse_regex 'This is a test: []{}.*potato'
  => /[ *.:T\[\]aehiopst{}]{28}/

Now with ranges!

These regexen match the entire string (if you added ^...$ it would still match, but I'm too lazy to do that and add the required length check). Also, I'm assuming the /s don't count for length. (If they did, it would be impossible for input of empty string.)

\$\endgroup\$
0
\$\begingroup\$

Python 3.2

If you wish for soemthing very short, as usual you can use python.

It is well known that you can do anything in python with few imports. In this case, this task is such simple that in python 3.2 you don't even need an include.

def reverse_regex(string):
    return '/.*/'

print (reverse_regex('dog'))
print (reverse_regex('I can haz a cheezburger.'))
print (reverse_regex('123-ABC-abc'))

You will see all these expression are valid.

UPDATE:

This new code (although a bit more long) is able to show multiple regex for eacah word.

def reverse_regex(string):
    print ('/.*/')
    print ('/'+string+'/')

reverse_regex('dog')
reverse_regex('I can haz a cheezburger.')
reverse_regex('123-ABC-abc')
\$\endgroup\$
  • \$\begingroup\$ the idea is that it should spit out different expressions for each string, and more than one of them \$\endgroup\$ – user70585 Feb 23 '14 at 18:39
  • \$\begingroup\$ thx, corrected. \$\endgroup\$ – Antonio Ragagnin Feb 23 '14 at 18:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.