用C#中的最后一个单词替换第一个单词

时间:2009-11-11 22:59:36

标签: c# regex replace

我想在C#中替换以下行。用替换单词替换第一个单词。我必须从最后一个单词中删除'['和']'。

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

输出应为

string newString="a18943 abc def abc"; 

由于

6 个答案:

答案 0 :(得分:17)

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

答案 1 :(得分:5)

为了好玩,我写了一个小基准来测试所有这些答案(包括我上面的其他答案)。这是我的工作站(32位Core 2 Duo @ 2.66GHz)上使用Release版本重复5M的结果:

  • LINQ:10.545秒
  • 我的Split + StringBuilder方式:3.633秒
  • wipeck的Split-and-Join方式! :3.32秒
  • (未编译)正则表达式:3.845秒
  • (已编译)正则表达式:12.431秒

结果:wipeck的Split-and-Join解决方案获胜,但(OP选择的)正则表达式解决方案只慢了15%,这让我感到惊讶。我期待100%或更差。感谢.NET Regex开发人员的速度。

我认为,我自己的解决方案(使用Split和StringBuilder)针对速度进行了优化,但需要更多代码并且实际上并没有快速实现。卫生署!

最令人惊讶的是,我尝试了一个编译的正则表达式解决方案,它比未编译的正则表达式慢了近3倍(我没有在结果中包含编译时间 - 包括编译它会更糟糕)。编译正则表达式的优势非常多。

正如我所料,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, "$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");
            }
        }
    }
}

答案 2 :(得分: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);

答案 3 :(得分:1)

尝试:

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

答案 4 :(得分:0)

这是一种方法。请注意,我假设字符串长度至少为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,修正了一个错字。让我编写代码而不先编译。 : - )

答案 5 :(得分:0)

这很难看,但确实有效。

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