Forse vi sarà capitato di dover inserire in qualche procedura una funzionalità di ricerca e/o filtro basata sui classici placeholder * (qualsiasi sequenza di carattere) e ? (qualsiasi carattere) usati come wildcard (cosidetti caratteri jolly).
Un po' di tempo fa ho scritto una funzione che utilizzando la classe RegEx (namespace System.Text.RegularExpressions) effettua il match su una stringa a partire da una wildcard costruita con i placeholder * e ?.
namespace TestWildCardMatch
{
public class UtilsString
{
private const string WILDCARD_PLACEHOLDER = @"[\.:\\\w\s]"; //.:\[0-9a-zA-Z_][whitespace]
public static bool IsMatchWithWildCard(string str, string wildCard, bool caseSensitive)
{
const string wildcharregexmulti = WILDCARD_PLACEHOLDER + "*";
const string wildcharregexone = WILDCARD_PLACEHOLDER + "{1}";
const string startmatch = @"^";
const string endmatch = @"$";
const string specialregexchars = @"[\^$.|+(){}"; //*? escluso
const string escape = @"\";
string strregex = caseSensitive ? wildCard : wildCard.ToLower();
//Caratteri speciali escluso *? wildchar personalizzate
foreach (char ch in specialregexchars)
strregex = strregex.Replace(string.Empty + ch, escape + ch);
//Traduzione wildchar *? in regexp
strregex = strregex.Replace("?", wildcharregexone);
strregex = strregex.Replace("*", wildcharregexmulti);
return Regex.IsMatch(caseSensitive ? str : str.ToLower(), startmatch + strregex + endmatch);
}
}
}
Notare che il carattere jolly è definito attraverso la costante WILDCARD_PLACEHOLDER comprende i simboli indicati nel commento e può essere esteso secondo le esigenze di applicazione.
Di seguito un esempio di utilizzo:
using System;
using System.Collections.Generic;
namespace TestWildCardMatch
{
public class UseWildCardMatch
{
public static void Test()
{
List<string> strings=new List<string>();
strings.Add("Marco");
strings.Add("Paolo");
strings.Add("Mirko");
strings.Add("Marta");
strings.Add("Simone");
List<string> matches = strings.FindAll(s => UtilsString.IsMatchWithWildCard(s, "??r*", false));
foreach (string matched in matches)
Console.WriteLine(matched);
}
}
}
Il risultato è il seguente: Marco, Mirko, Marta.