2009-11-11 91 views

回答

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

+1,非常简洁。 –

+0

其工作 我只是想了解它的工作方式如何 – NETQuestion

+0

很干净。我喜欢。我只是想知道RegEx在这里是否过度杀伤? –

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,修正了以上的错字。让我编写代码而不先编译。 :-)

+1

也可以使用.Trim(“[”,“]”)摆脱这可能是一个小清洁假设的最后一个字的括号总是开始与结束括号。 –

+0

好主意 - 修剪也快得多,速度更快 - 将所需时间缩短近一半。现在更新。 –

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

还,结果不是字符串,这是一个System.Linq.Enumerable.ConcatIterator –

+0

我会因为编辑它 - 当然newString将包含扁平化线。 –

+0

明白了。顺便说一句,这个性能比胜利(正则表达式)解决方案差3倍多。可能不会有太大的区别,因为即使最慢的解决方案在我的(慢速)PC上每秒钟运行速度为400k,但至少在这种情况下,我们应该考虑到正则表达式解决方案大大超过了LINQ解决方案。 –

1

尝试:

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

只是为了好玩,我写了一个小的基准为PErF测试所有这些问题的答案(包括我上面对方的回答)。这里是我的工作站上的结果(32位酷睿2 @主频为2.66GHz),为5M重复使用一个发布版本:

  • LINQ:10.545秒
  • 我的拆分+ StringBuilder的方式:3.633秒
  • wipeck的拆分 - 和 - 加入方式! :3.32秒
  • (未编译)的正则表达式:3.845秒
  • (编译)的正则表达式:12.431秒

结果:wipeck的分裂 - 和 - 加入溶液获胜,但(OP选择的)的正则表达式的解决办法是只有15%慢,这让我感到惊讶。我期待100%或更多。感谢.NET Regex开发人员的速度。

自己的解决方案(使用斯普利特和StringBuilder的)是,我认为,对速度进行了优化,但需要更多的代码,并没有真正让它快。卫生署!

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

LINQ是,如我所料,果然slow--所有这些额外的对象的开销和方法调用确实增加了。

下面是测试代码:

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

不错!感谢您发布此信息。虽然我的代码可能不是那么优雅,但它完成了工作:) –

相关问题