Заменить первое слово на последнее слово в C#
Я хочу заменить следующую строку в C#. Заменить первое слово последним. Я также должен удалить " ["и"] " из последнего слова.
string oldString = "200 abc def abc [a18943]"
выход должен быть!--3-->
string newString="a18943 abc def abc";
спасибо
6 ответов
просто для удовольствия, я написал небольшой тест для perf-test всех этих ответов (включая мой другой ответ выше). Вот результаты на моей рабочей станции (32-bit Core 2 Duo @ 2.66 GHz) для повторений 5M с использованием сборки выпуска:
- LINQ: 10.545 секунд
- мой Split + StringBuilder путь: 3,633 секунды wipeck пути! : 3.32 секунд
- (несжатое) регулярное выражение: 3,845 секунды
- (составитель) регулярное выражение : 12.431 секунды!--5-->
результаты: решение разделения и соединения wipeck выигрывает, но решение (OP-selected) regex было только на 15% медленнее, что меня удивило. Я ожидал 100% или даже хуже. Престижность разработчиков .NET Regex для скорости.
мое собственное решение (с использованием Split и StringBuilder) было, я думал, оптимизировано для скорости, но требует намного больше кода и на самом деле не делает его быстрым. Дох!
самое удивительное, я попробовал скомпилированное решение regex, и это было почти в 3 раза медленнее, чем несжатое регулярное выражение (и я не включил время компиляции в результаты, включая компиляцию, это было бы еще хуже). Так много для скомпилированного преимущества regex perf.
LINQ был, как я и ожидал, очень медленным - накладные расходы всех этих дополнительных объектов и вызовов методов действительно складываются.
вот тестовый код:
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, "");
}
}
Regex regex = new Regex(@"^(\w+)(.+) \[(\w+)\]$", RegexOptions.Compiled);
string newStringPreload = regex.Replace(oldString, "");
using (new Timer("(compiled) regex"))
{
for (int n = 0; n < reps; n++)
{
string newString = regex.Replace(oldString, "");
}
}
}
}
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);
это уродливо, но это работает.
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);
вот один из способов сделать это. Обратите внимание, что я предполагаю, что строка имеет длину не менее 1 слова.
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, исправлена опечатка выше. Служит мне для написания кода без компиляции. :-)