Poniższy kod zawiera wyrażenie regularne przeznaczone do wyodrębniania literału C#, ale wydajność dopasowywania do wyrażenia regularnego dla ciągów wejściowych składających się z więcej niż kilku znaków jest fatalna.Powolne działanie Regexa
class Program
{
private static void StringMatch(string s)
{
// regex: quote, zero-or-more-(zero-or-more-non-backslash-quote, optional-backslash-anychar), quote
Match m = Regex.Match(s, "\"(([^\\\\\"]*)(\\\\.)?)*\"");
if (m.Success)
Trace.WriteLine(m.Value);
else
Trace.WriteLine("no match");
}
public static void Main()
{
// this first string is unterminated (so the match fails), but it returns instantly
StringMatch("\"OK");
// this string is terminated (the match succeeds)
StringMatch("\"This is a longer terminated string - it matches and returns instantly\"");
// this string is unterminated (so the match will fail), but it never returns
StringMatch("\"This is another unterminated string and takes FOREVER to match");
}
}
Potrafię przekształcić wyrażenie regularne w inną formę, ale czy każdy może podać wyjaśnienie, dlaczego wydajność jest tak zła?
http://msdn.microsoft.com/en-us/magazine/ff646973.aspx – SLaks
Myślę, że to jest złe. '[^ \"] 'nie zatrzyma się na' \ "'. Zatrzyma się na '\' lub na '". Więc zatrzyma się na '\' 'n '. Czy to prawda? – xanatos
Może mógłbyś zmodyfikować swoje wyrażenie regularne, jeśli nie korzystasz z odnośników." \ "(?: (?: [^ \\\"] *) (?: \\.)?) * \ "". Oczywiście jeśli korzystasz z odnośników wstecz, zignoruj to. – Matthew