0

I am using a regular expression in an MVC app that allows users to create a username that includes many special characters, including *. One small problem, when searching for a user, we allow wildcard searches that use the * for the wildcard portion of the search. This is what the regular expression looks like on the creation side:

@"^([a-zA-Z0-9!\@#\$%\^&\*\(\)-_\+\.'`~/=\?\{\}\|]){6,255}$"

And here is what the regular expression would look like on the search side:

@"^([a-zA-Z0-9!\@#\$%\^&\*\(\)-_\+\.'`~/=\?\{\}\|]){6,255}$|([\w]){0,0})"

Is there a way to make this work properly by allowing a user to search a whole username that may include a * in the username, while still allowing other users to use the * as a wildcard search?

tereško
  • 58,060
  • 25
  • 98
  • 150
Skrubb
  • 531
  • 1
  • 6
  • 25
  • Explain a bit please? – Skrubb Apr 18 '14 at 19:29
  • See [this question](http://stackoverflow.com/q/188892/1578604) (I actually didn't know that C# didn't have an in-built way to use glob type matching... I'm really surprised.) – Jerry Apr 18 '14 at 19:29
  • FYI, `[a-zA-Z0-9!\@#\$%\^&\*\(\)-_\+\.'\`~/=\?\{\}\|]` is `[a-zA-Z0-9!@#$%^&*()_+.'\`~=?{}|-]`. Here the only character special in a character class is `-`, and one of the only you didn't escape... Putting it at the end escapes it. – Robin Apr 18 '14 at 19:48

1 Answers1

3

Short of reading the user's mind there's really no way to know if they meant * literally or as a wildcard. I'd recommend running the search both ways and sorting the results with the literal interpretation given higher precedence.

Here's approximately what an implementation might look like, with the search details abstracted away in some DoSearch method:

IList<Result> GetResults(string input)
{
    var expr = Regex.Escape(input);

    // search once with * as a literal:
    var results1 = DoSearch(expr);

    // replace the * literal with regex snippet:
    expr = expr.Replace("\\*", "(.*)");

    // search again with * as a wildcard
    var results2 = DoSearch(expr);

    // literal gets precidence
    return results1.Concat(results2).ToList();
}
Todd Menier
  • 37,557
  • 17
  • 150
  • 173