Reverse Regular expressions

3

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

user70585

Posted 2014-02-23T16:52:05.000

Reputation: 181

Question was closed 2014-02-23T19:18:19.833

3I think the spec could do with tightening. There are countably infinitely many families of countably infinitely many regexes which match any given string. – Peter Taylor – 2014-02-23T17:24:54.463

What if the input string is longer than 30 chars? – Doorknob – 2014-02-23T18:10:56.863

@doorknob good point, will revise again – user70585 – 2014-02-23T18:11:37.930

Now your sample output violates your own rules. – Doorknob – 2014-02-23T18:15:29.247

Will fix :P where would I be without you... – user70585 – 2014-02-23T18:16:29.763

1

Maybe in the sandbox: http://meta.codegolf.stackexchange.com/questions/954/proposed-questions-sandbox-mark-8

– None – 2014-02-23T19:17:25.140

Answers

1

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

Doorknob

Posted 2014-02-23T16:52:05.000

Reputation: 68 138

0

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

Antonio Ragagnin

Posted 2014-02-23T16:52:05.000

Reputation: 1 109

the idea is that it should spit out different expressions for each string, and more than one of them – user70585 – 2014-02-23T18:39:58.487

thx, corrected. – Antonio Ragagnin – 2014-02-23T18:42:28.070