I am not sure if this question belongs here or on StackOverflow since my implementation, which compiles and sort of works is not the right solution, because I have not fully decided on what the behavior should be, and I wanted to solicit some input on that.
Problem: I want to have a super-easy and powerful look-up dialog that is optimized mostly for non-technical users, but allows some basic regex as well. The emphasis is on making it easy for the users and so it is OK to have some complexity in the implementation as the result.
I am after a mix of power and simplicity. What I do not want is a relatively complex dialog like this one: http://teusje.files.wordpress.com/2011/09/vs2010-replace-in-files-regex.png?w=584
So, the user does a look-up by typing some text in the text box and when he/she tabs off, I intercept this even and try to find the match(es) if any. Suppose the user is searching for a month name (which is not a perfect example since a combo box would be better, but I do need a concrete example without disclosing any secrets. There are many more overall choices to begin with - say anywhere between 50 and 500).
- If the user entered "June" or "june", a single match for June will be returned (this is tried first).
- If the user entered "ju" or "Ju" or "jU", there is no exact match, but there are two months that start with "ju" - June and July, so the user sees a dialog that lists only these two choices and picks between them.
- If the user entered "*ber", I see that there are no exact matches and a prefix will not work, so then I try a regex, and while "*ber" might not work, if I replace it with ".*ber", I should get September through December.
- Now, if I enter "R", I get everything but May through August because every other month contains an "r" in it and may case-insensitive comparison does find it. I want to detect the fact that the user has not intended to use a regex here and I need a function that will return
trueorfalsebased on the string content. - Should the user enter "R*", this would stiff find everything because an empty string matches this and empty string is part of every string that is not
null. However, I can detect the case where there is a single character followed by a "" and replace that "" with a "+".
So, what I need now is a suggestion on how to improve the logic and the implementation of the following method, so that I can address the bullet point number 4. I understand that there is no perfect solution; I am looking for something that has a high probability of success when used by a non-technical or not very technical user.
[Obsolete("TODO: This method is imperfect to say the least.")]
public static bool PatternLooksLikeItContainsRegex(string pattern)
{
if (String.IsNullOrWhiteSpace(pattern))
{
return false;
}
// These are common uses but not everything.
// Some of these constants could be promoted as static fields / constants.
string anyCharRegex = ".*";
if (pattern.Contains(anyCharRegex))
{
return true;
}
var regexSuffixes = new string[] { "%", "*", "+", anyCharRegex };
if (regexSuffixes.Any(regSuff => pattern.EndsWith(regSuff)))
{
return true;
}
if (pattern.Contains("[^]") && pattern.Contains("]"))
{
return true; // Too lazy to check that '[^' comes before ']'.
// I am sure that there is a better approach ...
// based on a regex that detects a subset of a regex syntax perhaps?
}
return false;
}
[^0-9]{3,5}, more like 'App*` orMy [c-p]+orHello [a-k]*and that is pretty complex already. It should be like a crossword puzzle helper for amateurs without having them learn everything about regular expressions or worry about the exact length of the string by specifying a placeholder for every character. C) "Regex" will scare users. Wildcards won't. – Leonid Oct 8 '12 at 22:50