2009-11-11 89 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

不錯!感謝您發佈此信息。雖然我的代碼可能不是那麼優雅,但它完成了工作:) –

相關問題