2010-01-18 3 views

Répondre

10

Que diriez-vous:

public static int MyReplace(ref string source, 
    string org, string replace, int start, int max) 
{ 
    if (start < 0) throw new System.ArgumentOutOfRangeException("start"); 
    if (max <= 0) return 0; 
    start = source.IndexOf(org, start); 
    if (start < 0) return 0; 
    StringBuilder sb = new StringBuilder(source, 0, start, source.Length); 
    int found = 0; 
    while (max-- > 0) { 
     int index = source.IndexOf(org, start); 
     if (index < 0) break; 
     sb.Append(source, start, index - start).Append(replace); 
     start = index + org.Length; 
     found++; 
    } 
    sb.Append(source, start, source.Length - start); 
    source = sb.ToString(); 
    return found; 
} 

il utilise StringBuilder pour éviter beaucoup de string intermédiaires s; Je ne l'ai pas testé rigoureusement, mais cela semble fonctionner. Il essaie également d'éviter un string supplémentaire lorsqu'il n'y a pas de correspondance.

1

Pour commencer, essayer quelque chose comme ceci:

int count = 0; 
Regex.Replace(source, Regex.Escape(literal), (match) => 
{ 
    return (count++ > something) ? "new value" : match.Value; 
}); 
0

Pour remplacer seulement le premier match:

private string ReplaceFirst(string source, string oldString, string newString) 
    { 
     var index = source.IndexOf(oldString); 
     var begin = source.Substring(0, index); 
     var end = source.Substring(index + oldString.Length); 
     return begin + newString + end; 
    } 
0

Vous avez un bogue dans ce que vous allez manquer l'élément à remplacer si elle est au début.

modifier ces lignes;

int ret = start; // instead of zero, or you ignore the start parameter 

    // Find the next instance of the search string 
    // Do not skip olen for the first search! 
    int x = i == 0 ? source.IndexOf(org, ret) : source.IndexOf(org, ret + olen); 

Aussi votre routine fait 300 000 remplace une seconde sur ma machine. Êtes-vous sûr que ce sera un goulot d'étranglement?

Et je viens de trouver que votre code a aussi un problème si vous remplacez les textes plus volumineux par des textes plus petits.

0

Ce code est 100% plus rapide si vous avez quatre remplacements et environ 10% plus rapide avec un remplacement (plus rapide par rapport au code d'origine affiché). Il utilise le paramètre de démarrage spécifié et fonctionne lorsque vous remplacez des textes plus grands par des textes plus petits.

La solution de Mark Gravells est (pas d'infraction ;-) 60% plus lent que le code original et il renvoie également une autre valeur.

// Method signature, Only replaces first instance or how many are specified in max 
    public static int MyReplace(ref string source, string org, string replace, int start, int max) 
    { 
     var ret = 0; 
     int x = start; 
     int reps = 0; 
     int l = source.Length; 
     int lastIdx = 0; 
     string repstring = ""; 

     while (x < l) 
     { 
      if ((source[x] == org[0]) && (reps < max) && (x >= start)) 
      { 
       bool match = true; 
       for (int y = 1; y < org.Length; y++) 
       { 
        if (source[x + y] != org[y]) 
        { 
         match = false; 
         break; 
        } 
       } 
       if (match) 
       { 
        repstring += source.Substring(lastIdx, x - lastIdx) + replace; 
        ret = x; 
        x += org.Length - 1; 
        reps++; 
        lastIdx = x + 1; 
        // Done? 
        if (reps == max) 
        { 
         source = repstring + source.Substring(lastIdx); 
         return ret; 
        } 
       } 
      } 
      x++; 
     } 

     if (ret > 0) 
     { 
      source = repstring + source.Substring(lastIdx); 
     } 

     return ret; 
    } 
Questions connexes