1

I'm fiddling around with MongoDB and there is something I stumbled upon. I'd like to make a simple application in which the user can search all documents in a collection, getting the documents of which the key username contains a certain user inputted value.

For implementing "contains" it appears a regular expression can be used. This works fine, but how can I convert user input into a regular expression? The problem is that simply doing ...

new RegExp(value);

... does not work because of special characters (like (, [ etc.). This means the user cannot do a query containing ( this way.

I thought escaping everything would do the job:

new RegExp(value.replace(/./g, function(x) {
    return "\\" + x;
});

... but it doesn't because some escaped characters are also special (e.g. \d), so this way non-special characters become special.

I'm a bit lost how I could turn a user inputted value into a regular expression. Or is there perhaps a better way of doing a query for all documents of which a key contains a certain user inputted value?

Community
  • 1
  • 1
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • you could, of course, tell them that they need to provide a regular expression to search, or give the option, then tell them that `.`, `(`, and `[` need to be escaped (also `^`, and `$` and a few more I'm forgetting right now) – Code Jockey Nov 30 '11 at 20:10
  • 1
    @Code Jockey: Let's pretend the target audience does not know about regular expressions and escaping. Even if the user did know these things, I'd need to escape server-side for security. – pimvdb Nov 30 '11 at 20:16

1 Answers1

2

Implementation:

Based on this source.

var oldText = "[hello, world :) ]";
var sre = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
var newText = oldText.replace(sre, '\\$1'); // "\[hello, world :\) \]"

Further explanation:

sre is a regular expression that is matching all possible special characters and is using parentheses so it can reference matched parts.

Incomplete sre example:

/(\/|\.|\\)/g 

This will try to match for any of this characters: "/", "." and "\". Using then

text.replace(sre, '\\$1');

will escape every single matched character in text with "\". So it will replace "." with "\.", etc.

kubetz
  • 8,485
  • 1
  • 22
  • 27