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\$

closed as too broad by Peter Taylor, ProgramFOX, ace, Justin, Hosch250 Feb 23 '14 at 19:18

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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\$ – John Doe 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\$ – Hosch250 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\$ – John Doe 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.