2009-11-11 1 views
8

Je souhaite remplacer la ligne suivante par C#. Remplacer le premier mot par le dernier mot. Je dois aussi enlever '[' et ']' du dernier mot.Remplacer le premier mot par le dernier mot en C#

string oldString = "200 abc def abc [a18943]" 

sortie doit être

string newString="a18943 abc def abc"; 

Merci

Répondre

17
string newString = Regex.Replace(oldString, @"^(\w+)(.+) \[(\w+)\]$", "$3$2"); 
+0

+1, très concis. –

+0

Son travaillé Je veux juste comprendre comment il woring – NETQuestion

+0

Très propre. J'aime ça. Je me demande juste si RegEx est exagéré ici? –

0

est ici une façon de le faire. Notez que je suppose que la chaîne a au moins 1 mot.

string oldString = "200 abc def abc [a18943]"; 
string[] words = oldString.Split(' '); 
StringBuilder sb = new StringBuilder(words[words.Length-1].Trim('[', ']')); 
for (int i = 1; i < words.Length-1; i++) 
{ 
    sb.Append (" "); 
    sb.Append (words[i]); 
} 
string newString = sb.ToString(); 

OOPS, correction d'une faute de frappe ci-dessus. Me sert pour écrire du code sans compiler d'abord. :-)

+1

pourrait également utiliser .Trim (« [ », « ] ») pour se débarrasser des supports qui peuvent être un peu plus propre en supposant que le dernier mot commence et se termine toujours avec les supports. –

+0

Bonne idée - Trim est aussi beaucoup, beaucoup plus rapide - réduit le temps nécessaire pour exécuter cela presque de moitié. Mise à jour maintenant –

0

C'est moche, mais ça marche.

string[] a = oldString.Split(' '); 
var result = a.Skip(a.Length-1) 
      .Select(w => w.Replace("[","").Replace("]","")) 
      .Concat(a.Take(a.Length -1).Skip(1)).ToArray(); 

var newString = string.Join(" ", result); 
+0

aussi, le résultat n'est pas une chaîne, c'est un System.Linq.Enumerable.ConcatIterator –

+0

Je l'ai édité depuis - newString contiendra bien sûr la chaîne aplatie. –

+0

J'ai compris. BTW, perf de ceci est plus de 3 fois pire que la solution gagnante (regex). Probablement ne fera pas beaucoup de différence puisque même la solution la plus lente a couru 400k par seconde sur mon PC (lent), mais à la réflexion qu'une solution regex bat une solution LINQ par une large marge, au moins dans ce cas. –

1

Essayez:

Regex  : ^\w+(.*\s)\[(\w+)]$ 
Replacement : $2$1 
4
 string oldString = "200 abc def abc [a18943]"; 
     string[] values = oldString.Split(' '); 
     string lastWord = values[values.Length - 1].Trim('[', ']'); 
     values[0] = lastWord; 
     string newString = string.Join(" ", values, 0, values.Length - 1); 
5

Juste pour le plaisir, j'ai écrit un petit point de repère pour PERF-test de toutes ces réponses (y compris mon autre réponse ci-dessus). Les résultats ici sur mon poste (32 bits Core 2 Duo @ 2.66GHz) pour 5 millions de répétitions en utilisant une version Release:

  • LINQ: 10.545 secondes
  • mon chemin de Split + StringBuilder: 3.633 secondes
  • de Split de wipeck -et-Join façon! : 3,32 secondes
  • (décompilé) regex: 3.845 secondes
  • (compilé) regex: 12.431 secondes

Résultats: de wipeck fendit et-Join solution gagne, mais la solution de regex (sélectionné OP-) était seulement 15% plus lent, ce qui m'a surpris. Je m'attendais à 100% ou plus pire. Bravo aux développeurs .NET Regex pour la rapidité. Ma propre solution (en utilisant Split et StringBuilder) a été, je pense, optimisée pour la vitesse, mais nécessite beaucoup plus de code et ne rend pas vraiment rapide. Doh! Plus étonnamment, j'ai essayé une solution regex compilée et elle était presque 3x plus lente que la regex non compilée (et je n'ai pas inclus le temps de compilation dans les résultats - y compris la compilation ce serait encore pire). Tellement pour l'avantage compilé de performance de regex. LINK était, comme je m'y attendais, vraiment lent - le surcoût de tous ces objets supplémentaires et appels de méthode s'ajoute vraiment.

est ici le code de test:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 

class Timer : IDisposable 
{ 
    private DateTime _start; 
    private string _name; 

    public Timer(string name) 
    { 
     _name = name; 
     _start = DateTime.Now; 
    } 
    public void Dispose() 
    { 
     TimeSpan taken = DateTime.Now - _start; 
     Console.WriteLine(string.Format ("{0} : {1} seconds", _name, taken.TotalMilliseconds/1000.0)); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     int reps = 5000000; 
     string oldString = "200 abc def abc [a18943]"; 

     using (new Timer("LINQ")) 
     { 
      for (int n = 0; n < reps; n++) 
      { 
       string[] a = oldString.Split(' '); 
       var result = a.Skip(a.Length - 1) 
          .Select(w => w.Replace("[", "").Replace("]", "")) 
          .Concat(a.Take(a.Length - 1).Skip(1)).ToArray(); 

       var newString = string.Join(" ", result); 
      } 
     } 

     using (new Timer("my Split + StringBuilder way")) 
     { 
      for (int n = 0; n < reps; n++) 
      { 
       string[] words = oldString.Split(' '); 
       StringBuilder sb = new StringBuilder(words[words.Length - 1].Trim('[', ']')); 
       for (int i = 1; i < words.Length - 1; i++) 
       { 
        sb.Append(' '); 
        sb.Append(words[i]); 
       } 
       string newString = sb.ToString(); 
      } 
     } 

     using (new Timer("wipeck's Split-and-Join way!")) 
     { 
      for (int n = 0; n < reps; n++) 
      { 
       string valueString = "200 abc def abc [a18943]"; 
       string[] values = valueString.Split(' '); 
       string lastWord = values[values.Length - 1]; 
       lastWord = lastWord.Trim('[', ']'); 
       values[0] = lastWord; 
       string movedValueString = string.Join(" ", values, 0, values.Length - 1); 
      } 
     } 

     using (new Timer("(uncompiled) regex")) 
     { 
      for (int n = 0; n < reps; n++) 
      { 
       string newString = Regex.Replace(@"^(\w+)(.+) \[(\w+)\]$", oldString, "$3$2"); 
      } 
     } 

     Regex regex = new Regex(@"^(\w+)(.+) \[(\w+)\]$", RegexOptions.Compiled); 
     string newStringPreload = regex.Replace(oldString, "$3$2"); 
     using (new Timer("(compiled) regex")) 
     { 
      for (int n = 0; n < reps; n++) 
      { 
       string newString = regex.Replace(oldString, "$3$2"); 
      } 
     } 
    } 
} 
+0

Nice! Merci d'avoir posté cela. Alors que mon code n'est peut-être pas si élégant, il fait le travail :) –