I wonder if it is possible to modify a wildcard expression that uses * and ? to transform it into a regular expression to verify if it matches some strings.
In other word, if I use filter (case insensitive): *bl?e* on those strings:
["Blue", "Black", "Red", "Light blue", "Light black"]
I want to get:
["Blue, "Light blue"].
Does anybody know how to do that with regular expression?
Is there a better way to do that other than using regular expression?
Added to better clarify my thought…
Ok! … as always, I thought I ask a super clear question and realize by the answers that I totally screw up my question. I would like to do a function that would filter a collection according to an expression (as a parameter to my function) that as same rules as dos (‘*’ ‘?’). I thought that using regex would be a nice idea. Am I right and what is the regex expression ? Also… I’m using C# and I wonder if I don not have access to anything that would do the job directly ?
I also look at (pretty good answer) How do I specify a wildcard (for ANY character) in a c# regex statement?
I finally used Glob class in .net Patterns and Practices library.
But as reference this is my code to translate Glob exp to RegEx:
using System.Text;
using System.Text.RegularExpressions;
namespace HQ.Util.General
{
public class RegexUtil
{
public const string RegExMetaChars = @"*?(){}[]+-^$.|\"; // Do not change the order. Algo depends on it (2 first chars should be dos like wildcard char)
// ******************************************************************
/// <summary>
/// Convert an filter expression with '*' (wildcard any char) and '?' (wildcard on char) into a valid regex and
/// strip any special regex character
/// </summary>
/// <param name="dosLikeExpressionFilter"></param>
/// <returns></returns>
public static string DosLikeExpressionFilterToRegExFilterExpression(string dosLikeExpressionFilter)
{
StringBuilder regex = new StringBuilder();
regex.Append("(?i)"); // Case insensitive
int startIndex = 0;
int count = dosLikeExpressionFilter.Length;
while (startIndex < count)
{
int metaIndex = RegExMetaChars.IndexOf(dosLikeExpressionFilter[startIndex]);
if (metaIndex >= 0)
{
if (metaIndex == 0)
{
regex.Append(".*");
}
else if (metaIndex == 1)
{
regex.Append(".");
}
else
{
regex.Append("\\");
regex.Append(dosLikeExpressionFilter[startIndex]);
}
}
else
{
regex.Append(dosLikeExpressionFilter[startIndex]);
}
startIndex++;
}
return regex.ToString();
}
// ******************************************************************
/// <summary>
/// See 'DosLikeExpressionFilterToRegExFilterExpression' description to see what type of Regex is returned
/// </summary>
/// <param name="dosLikeExpressionFilter"></param>
/// <returns></returns>
public static Regex DosLikeExpressionFilterToRegEx(string dosLikeExpressionFilter)
{
return new Regex(DosLikeExpressionFilterToRegExFilterExpression(dosLikeExpressionFilter));
}
// ******************************************************************
}
}
So
Bl?e(glob) becomesBl.e(regex), and*Bl?e*becomes.*Bl.e.*.As Joey correctly noted, you can (usually, depending on the regex engine) prepend
(?i)to your regex to make it case-insensitive.Be aware, though, that lots of characters that have no special meaning in globbing patterns do have special meaning in regex, so you can’t just do a simple search-and-replace from glob to regex.