Un simple (certains pourraient dire naïf) approche serait de créer un modèle de regex qui concaténer toutes les chaînes de recherche, séparés par l'opérateur alternance |
:
- Pour vos chaînes par exemple, que diriez-vous obtenir
KHTK|RAZ
.
- Pour avoir les préfixes de capture regex, nous incluons ces préfixes dans le motif, par ex.
K|KH|KHT|KHTK|R|RA|RAZ
. Enfin, pour nous assurer que ces chaînes sont capturées uniquement en entier et non en tant que partie de chaînes plus grandes, nous allons faire correspondre les opérateurs de début et de fin de ligne ainsi que le début et la fin de chaque chaîne. , respectivement: ^K$|^KH$|^KHT$|^KHTK$|^R$|^RA$|^RAZ$
Nous nous attendons à ce que l'implémentation de la classe Regex effectue la lourde tâche de conversion de la longue chaîne de motifs regex en un matcher efficace.
Le programme exemple génère ici 10 000 chaînes aléatoires et une expression régulière correspondant exactement à ces chaînes et à tous leurs préfixes. Le programme vérifie ensuite que la regex correspond bien à ces chaînes, et combien de temps cela prend.
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication
{
class Program
{
private static Random r = new Random();
// Create a string with randomly chosen letters, of a randomly chosen
// length between the given min and max.
private static string RandomString(int minLength, int maxLength)
{
StringBuilder b = new StringBuilder();
int length = r.Next(minLength, maxLength);
for (int i = 0; i < length; ++i)
{
b.Append(Convert.ToChar(65 + r.Next(26)));
}
return b.ToString();
}
static void Main(string[] args)
{
int stringCount = 10000; // number of random strings to generate
StringBuilder pattern = new StringBuilder(); // our regular expression under construction
HashSet<String> strings = new HashSet<string>(); // a set of the random strings (and their
// prefixes) we created, for verifying the
// regex correctness
// generate random strings, track their prefixes in the set,
// and add their prefixes to our regular expression
for (int i = 0; i < stringCount; ++i)
{
// make a random string, 2-5 chars long
string nextString = RandomString(2, 5);
// for each prefix of the random string...
for (int prefixLength = 1; prefixLength <= nextString.Length; ++prefixLength)
{
string prefix = nextString.Substring(0, prefixLength);
// ...add it to both the set and our regular expression pattern
if (!strings.Contains(prefix))
{
strings.Add(prefix);
pattern.Append(((pattern.Length > 0) ? "|" : "") + "^" + prefix + "$");
}
}
}
// create a regex from the pattern (and time how long that takes)
DateTime regexCreationStartTime = DateTime.Now;
Regex r = new Regex(pattern.ToString());
DateTime regexCreationEndTime = DateTime.Now;
// make sure our regex correcly matches all the strings, and their
// prefixes (and time how long that takes as well)
DateTime matchStartTime = DateTime.Now;
foreach (string s in strings)
{
if (!r.IsMatch(s))
{
Console.WriteLine("uh oh!");
}
}
DateTime matchEndTime = DateTime.Now;
// generate some new random strings, and verify that the regex
// indeed does not match the ones it's not supposed to.
for (int i = 0; i < 1000; ++i)
{
string s = RandomString(2, 5);
if (!strings.Contains(s) && r.IsMatch(s))
{
Console.WriteLine("uh oh!");
}
}
Console.WriteLine("Regex create time: {0} millisec", (regexCreationEndTime - regexCreationStartTime).TotalMilliseconds);
Console.WriteLine("Average match time: {0} millisec", (matchEndTime - matchStartTime).TotalMilliseconds/stringCount);
Console.ReadLine();
}
}
}
Sur une boîte Intel Core2 Je reçois les chiffres suivants pour 10.000 cordes:
Regex create time: 46 millisec
Average match time: 0.3222 millisec
En augmentant le nombre de chaînes de 10 fois (à 100 000), je reçois:
Regex create time: 288 millisec
Average match time: 1.25577 millisec
Ceci est plus élevé, mais la croissance est inférieure à linéaire. La consommation de mémoire de l'application (10 000 chaînes) a commencé à ~ 9 Mo, a atteint un sommet de ~ 23 Mo qui devait contenir à la fois la regex et l'ensemble de chaînes et a chuté à ~ 16 Mo vers la fin. vos propres conclusions à partir de cela - le programme n'optimise pas pour taquiner la consommation de mémoire regex des autres structures de données.
Ce n'est pas une réponse à votre question, mais puisque vous mentionnez que vous êtes nouveau à RegEx, je voudrais signaler une excellente ressource que j'ai récemment trouvée pour apprendre et tester le http://gskinner.com/RegExr de RegEx/ –