2009-07-23 6 views
0

Voici une autre ancienne fonction je de mon C# 1 jours, ce serait une façon plus élégante de l'écrire:Quelle est la manière la plus élégante de mettre en œuvre GetTextAfterMarker()

//method: gets the text in a string in front of a marker, if marker is not there, then return empty string 
//example: GetTextAfterMarker("documents/jan/letter043.doc","/") returns "documents" 
//example: GetTextAfterMarker("letter043.doc","/") returns "" 
//rank:8 
public static string GetTextAfterMarker(string line, string marker) { 
    string r = ""; 

    int pos = line.IndexOf(marker); 
    if(pos != -1) { 
     r = line.Substring(pos+(marker.Length),line.Length-pos-(marker.Length)); 
    } else { 
     r = ""; 
    } 

    return r; 
} 
+2

ce qui est une question de savoir comment? –

+0

Je pense qu'il y a un bug dans votre code. L'utilisation de pos + (marker.Length) comme position de départ pour Substring va commencer après le marqueur, et retournera, dans votre premier exemple, "jan/letter043.doc". Donc soit votre code a un bug ou vous avez mal nommé la fonction. –

+0

désolé, le nom de la fonction est faux, mais Fredrik Mörk m'a aidé à écrire de cette façon: http://stackoverflow.com/questions/1172216/how-can-i-refactor-this-c-code-using-split –

Répondre

1

Je trouve le nom un peu étrange, étant donné qu'il doit retourner le texte figurant avant le premier marqueur. Mais celui-ci fait le même travail, je pense (je pris la liberté de changer le nom):

public static string GetTextBeforeMarker(string line, string marker) 
{ 
    if (line == null) 
    { 
     throw new ArgumentNullException("line"); 
    } 

    if (marker == null) 
    { 
     throw new ArgumentNullException("marker"); 
    } 

    string result = line.Split(new string[] { marker }, StringSplitOptions.None)[0]; 
    return line.Equals(result) ? string.Empty : result; 
} 

Explication: diviser la chaîne en un tableau en utilisant le marqueur argument partagé. Si le premier élément du résultat est le même que l'entrée, le marqueur n'était pas dans la chaîne, donc nous retournons une chaîne vide, sinon nous retournons le premier élément (qui est le texte jusqu'à la première occurrence du marqueur).

+0

C'est une bonne utilisation de Split(), j'avais l'habitude de créer GetTextAfterMarker ici, mais il pourrait utiliser un refactoring puisque je ne savais pas comment faire référence à Count() entre parenthèses: http://stackoverflow.com/questions/ 1172216/how-i-refactor-this-c-code-using-split –

0

Vous pouvez utiliser des expressions régulières :

public static string GetTextBeforeMarker(string line, string marker) 
    { 
     if (String.IsNullOrEmpty(line)) 
      throw new ArgumentException("line is null or empty.", "line"); 
     if (String.IsNullOrEmpty(marker)) 
      throw new ArgumentException("marker is null or empty.", "marker"); 
     string EscapedMarker = Regex.Escape(marker); 
     return Regex.Match(line, "([^" + EscapedMarker + "]+)" + EscapedMarker).Groups[1].Value; 
    } 
+0

It échoue sur le deuxième exemple dans les commentaires de code dans la question –

+0

Merci - Mise à jour. –

1

Ai-je raté quelque chose? Cela ne serait-il pas plus simple? Aussi je préfère Substring à Split.

public static string GetTextAfterMarker(string line, string marker) { 
    int pos = line.IndexOf(marker); 
    if (pos == -1) 
     return string.Empty; 
    return line.Substring(0,pos); 
} 
+0

Cela ressemble à la meilleure pour moi. Je ne peux pas imaginer que Split soit plus efficace que IndexOf suivi de Substring. Et si vous voulez obtenir vraiment laconique: return ((pos = line.IndexOf (marqueur) == -1)? String.Empty: line.Substring (0, pos); –

+0

J'ai couru quelques tests sur les deux solutions (couru 100000 itérations de chaque, mesurant le temps avec Stopwatch), et trouvé - quelque peu à ma grande surprise - que l'approche Split fonctionnait plutôt deux fois plus vite que l'approche IndexOf/Substring (et cela inclut les vérifications nulles dans ma méthode). L'approche Split semble aussi garder sa vitesse quand on lui donne des chaînes sans le marqueur, un scénario qui semble ralentir la solution IndexOf/Substring: –

+0

..et ces résultats * vraiment * ont éveillé ma curiosité (je les ai trouvés étranges), donc je Si l'appel à IndexOf de bruno est changé en 'line.IndexOf (marker, 0, line.Length, StringComparison.Ordinal), il devient beaucoup plus rapide, et la solution IndexOf/Substring gagne: o) –

0
public static string GetTextBeforeMarker(string line, string marker) { 
    return GetTextAfterMarker(string line, string marker); 
} 
Questions connexes