2009-09-15 8 views
2

J'ai une liste de 400 chaînes qui se terminent tous dans "_GONOGO" ou "_ALLOC". Lorsque l'application démarre, j'ai besoin de supprimer "_GONOGO" ou "_ALLOC" de chacune de ces chaînes. J'ai essayé ceci: 'string blah = Regex.Replace (string, "(_GONOGO | _ALLOC)", ""));'Regex.Replace beaucoup plus lent que l'instruction conditionnelle en utilisant String.Contains

mais il est beaucoup plus lent qu'une simple déclaration conditionnelle comme ceci:

if (string.Contains("_GONOGO")) 
      // use Substring 
else if (string.Contains("_ALLOC")) 
      // use Substring w/different index 

Je suis nouveau à des expressions régulières, donc je suis en espérant que quelqu'un a une meilleure solution ou je fais quelque chose horriblement mal . Ce n'est pas une grosse affaire, mais ce serait bien de transformer cette ligne de 4 lignes en une simple ligne regex.

+1

Est-ce que votre regex fonctionne mieux si vous mettez une ancre '$' à la fin du motif? –

+0

Vous devez utiliser 'EndsWith' au lieu de' Contient'. En plus d'être plus correct, c'est plus rapide. :) –

Répondre

8

Bien qu'il soit RegEx, vous pourriez faire

string blah = string.Replace("_GONOGO", "").Replace("_ALLOC", ""); 

RegEx est idéal pour des expressions complexes, mais les frais généraux peuvent parfois être trop pour des opérations très simples comme celui-ci.

+0

Merci, c'est très bien - regex n'était pas une exigence que je voulais juste à une ligne. – alexD

4

Les remplacements d'expressions régulières peuvent fonctionner plus rapidement si vous compilez d'abord l'expression régulière. Comme dans:

Regex exp = new Regex(
    @"(_GONOGO|_ALLOC)", 
    RegexOptions.Compiled); 

exp.Replace(string, String.Empty); 
+0

Notez également (à partir de MSDN) "La classe Regex est immutable (lecture seule) et est intrinsèquement thread-safe." Vous pouvez le créer une fois et l'affecter à un champ en lecture seule statique. Voir http://www.acorns.com.au/blog/?p=136 – TrueWill

+0

Et des Archives Atwood: http://www.codinghorror.com/blog/archives/000228.html – TrueWill

3

Ceci est attendu; En général, manipuler une chaîne à la main sera plus rapide que d'utiliser une expression régulière. Utiliser une regex implique de compiler une expression dans un arbre regex, et cela prend du temps.

Si vous utilisez cette expression régulière à plusieurs endroits, vous pouvez utiliser l'indicateur RegexOptions.Compiled pour réduire l'en-tête par match, comme David le décrit dans sa réponse. D'autres experts en regex pourraient avoir des conseils pour améliorer l'expression. Vous pourriez envisager de coller avec le String.Replace, cependant; c'est rapide et lisible.

1

Si elles terminent tous dans l'un de ces modèles, il serait probablement plus rapide de supprimer remplacer complètement et l'utilisation:

string result = source.Substring(0, source.LastIndexOf('_')); 
1

Lorsque vous avez que beaucoup d'informations au sujet de votre domaine de problème, vous pouvez faire des choses assez simples :

const int AllocLength = 6; 
const int GonogoLength = 7; 
string s = ...; 
if (s[s.Length - 1] == 'C') 
    s = s.Substring(0, s.Length - AllocLength); 
else 
    s = s.Substring(0, s.Length - GonogoLength); 

Ceci est théoriquement plus rapide que Abraham's solution, mais pas aussi flexible. Si les cordes ont une chance de changer alors celui-ci souffrirait de problèmes de maintenabilité que le sien ne fait pas.

Questions connexes