8
votes

Remplacer le premier mot avec le dernier mot en c #

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

string newString="a18943 abc def abc"; 


0 commentaires

6 Réponses :


0
votes

Voici une façon de le faire. Notez que je suppose que la chaîne est d'au moins 1 mot long.

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();


2 commentaires

Pourrait également utiliser .trim ('[', ']') pour se débarrasser des supports pouvant être un peu plus propre en supposant que le dernier mot commence et se termine toujours avec les crochets.


Bonne idée-- La garniture est également beaucoup, beaucoup plus rapide, réduit le temps nécessaire pour l'exécuter presque en deux. Mise à jour maintenant.



0
votes

C'est moche, mais ça marche. XXX


3 commentaires

En outre, le résultat n'est pas une chaîne, c'est un système.Linq.Enumérable.ConCAserator


Depuis la modification de la modification, je voudrais bien entendu la chaîne aplatie.


J'ai compris. BTW, Perf de ceci est plus de 3 fois pire que la solution gagnante (regex). Ne fera probablement pas une grande partie de la différence car même la solution la plus lente a couru 400k par seconde sur mon PC (lent), mais la nourriture pour penser qu'une solution de regex bat une solution LINQ par une large marge, du moins dans ce cas.



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

5 commentaires

Très propre. Je l'aime bien. Je me demande simplement si Regex est surchargée ici?


@NetQuestion: Le modèle Regex définit 3 groupes entre parenthèses. Il correspondra à tout fragment qui contient un mot (\ w +) suivi de n'importe quel caractère (. +) Et se terminant par un mot entouré de [et] (\ [(\ w) \] $. Le remplacement est une concaténation des backreferences au 3ème groupe et au 2e groupe.


Et c'est trop vite-- J'ai écrit une référence rapide des solutions sur ce fil, et la regex était à moins de 15% du gagnant, mais était de loin le code le plus propre. Cela m'a surpris ... J'aurais attendu que les regexnes soient plus lentes. Bon travail!


Je dirais concis, mais obtus. Qui pourrait jamais déboguer, que s'il y avait un problème avec ça !? Peut-être que c'est juste moi. Je préférerais que l'un de mes devs me donne le code Wilpeck que le regex n'importe quel jour.


@Scott P, j'ai rencontré cet argument souvent. Je peux apprécier le code concis comme cette réponse ici. Je pense que l'argument pourrait aller dans les deux sens de la maintenance, ma solution peut être plus facile à comprendre à première vue, mais il y a plus de code à considérer si les exigences changent. Je suppose que lorsque les gens posent ce genre de questions, je ne vois pas toujours regex ni linq comme ma première solution, principalement parce que je ne comprends pas toujours ce qui se passe sous les couvertures avec Linq ou les classes de regex. Je préférerais utiliser Linq ou Regex lorsque j'en ai vraiment besoin contre l'utiliser hors d'habitude.



1
votes

Essayez:

 Regex       : ^\w+(.*\s)\[(\w+)]$
 Replacement : $2$1


0 commentaires

4
votes
        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);

0 commentaires

5
votes

Juste pour le plaisir, j'ai écrit un petit point de référence pour tester toutes ces réponses (y compris mon autre réponse ci-dessus). Voici les résultats de mon poste de travail (Core 2 32 bits Duo @ 2,66 GHz) pour des répétitions de 5 m à l'aide d'une version de version:

  • LINQ: 10.545 secondes li>
  • My Split + StringBuilder Way: 3.633 secondes Li>
  • Wipeck's Split-and-Inscrivez-vous! : 3,32 secondes li>
  • (non pondéré) Regex: 3,845 secondes Li>
  • (compilé) Regex: 12.431 secondes Li> ul>

    Résultats: La solution Split-and-Rejoindre WIPCK WINS, mais la solution (op-sélectionnée) Regex n'était que 15% plus lente, ce qui m'a surpris. Je m'attendais à 100% ou plus pire. Félicitations aux développeurs de .net Regex à la vitesse. P>

    Ma propre solution (en utilisant Split and StringBuilder) était, j'ai pensé, optimisée pour la vitesse, mais nécessite beaucoup plus de code et ne le rend pas rapide. Doh! P>

    surprenant, j'ai essayé une solution de regex compilée et il était presque 3 fois plus lent que la regex non pondérée (et je n'ai pas inclus le temps de compilation dans les résultats, y compris la compilation, y compris la compilation. pire). Voilà pour la compilée Regex Perf avantage. P>

    Linq était, comme je m'y attendais, vraiment lent - les frais généraux de tous ces objets et procédés supplémentaires s'additionnent vraiment. P>

    Voici le code de test: P>

    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");
                }
            }
        }
    }
    


1 commentaires

Joli! Merci d'avoir posté ceci. Bien que mon code ne soit peut-être pas tout ce qui est élégant, cela fait le travail :)