2010-02-22 78 views
6

字符串格式總是像這樣「FirstName = ABC; LastName = XZY;用戶名= User1;密碼= 1234」。如何從一個字符串使用C#子字符串?

我需要唯一的UserName值(在這種情況下是'User1')。我想在使用子字符串方法(或其他)的最小代碼行中實現這一點。

幫助?

+0

當一個問題有非常明確的答案像這樣它總是一件有趣的我看有多少不同的解決方案多所社區提供。 –

+0

有一點需要注意:輸入字符串有一個名爲「User ** n ** name」的字段。然後您要求「User ** N ** ame」字段。解析字符串時要小心套話。當然有處理這個問題的方法。 –

回答

4

即使值對以不同的順序給出,該方法仍然有效。它在分號上分開,用「用戶名」找到該項目,然後返回等號後面的內容。

string theString = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string username = theString.Split(";").Where(s => s.Split("=")[0].Equals("Username")).ToArray()[0].Split("=")[1]; 
+0

@Aaron:對不起,是語法oke。我正在接近.ToArray [0] ..錯誤。 – Jango

+0

@ user144842:您在我的示例中遇到了錯誤! ToArray之後應該有括號。我已經更新了我的答案。 – Aaron

+0

這將是一半VB和一半C#...可能都是他的頭頂。 –

12

看起來像一個分隔的字符串,所以這會工作:

string result = myString.Split(';')[2].Split('=')[1]; 

但是,如果有人更改值對訂單,這將打破。

有更好的方法可以解決這個問題,如果順序改變,參數的數量不同等等 - 比如Michael發佈的正則表達式,或者許多人發佈的Linq查詢。

+0

打我吧:( –

+3

我很欣賞你試圖儘可能縮短它,但我認爲我們有最近看到的最醜陋的代碼的贏家(沒有任何意圖!) – brian

+0

我wouldn不要說它有史以來最醜陋的代碼,但用戶得到了他想要的東西..... –

4

最少的代碼行數並不總是最好的指標,但你可以用正則表達式來做你所需要的。

+1

這有多奇怪,這可能是我見過正則表達式的第一次建議,它是一個有效的答案。 :p – Tanzelax

+0

難道你沒有聽說過 - 有些人在遇到問題時想:「我知道,我會用正則表達式。」現在他們有兩個問題。傑米Zawinski – Oded

+0

@Tanzelax:正則表達式成爲新的JQuery? – brian

1
 string t = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
     string name = t.Split(';')[2].Split('=')[1]; 
7

這裏是一個替代的解決方案(從別人不太一樣,但我認爲這是更簡單),無論其將工作秩序。

var input = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 

Assert.AreEqual("User1", input 
    .Split(';') 
    .Select(item => item.Split('=')) 
    .Where(pair => pair[0].Equals("Username")) 
    .Single()[1]); 
+0

當字符串沒有「用戶名」時失敗。 –

+0

如果可能沒有用戶名,可以在'.Single()'之前添加'.Select(pair => pair [1])'並將'.Single()'改爲'.SingleOrDefault()'。那麼如果沒有用戶名,你就會得到空值。 –

15

爲了完整起見,這裏是正則表達式的方法。如果訂單改變,這也將起作用。

// using System.Text.RegularExpressions; 

string test1 = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string test2 = "FirstName=ABC;LastName=XZY;Password=1234;Username=User1"; 
string test3 = "FirstName=ABC;LastName=XZY;Password=1234"; 

string regexPattern = @"(?<=Username=)[^;\n]*"; 
var userName1 = Regex.Match(test1, regexPattern).Value; // User1 
var userName2 = Regex.Match(test2, regexPattern).Value; // User1 
var userName3 = Regex.Match(test3, regexPattern).Value; // string.Empty 

// Compiling can speed up the Regex, at the expense of longer initial Initialization 
// Use when this is called often, but measure. 

Regex compiledRx = new Regex(regexPattern,RegexOptions.Compiled); 
var userNameCompiled1 = compiledRx.Match(test1).Value; // User1 
var userNameCompiled2 = compiledRx.Match(test2).Value; // User1 
var userNameCompiled3 = compiledRx.Match(test3).Value; // string.Empty 
+1

這實際上是應用正則表達式的好地方。好東西。 –

3

雖然分裂的答案是「OK」,如果什麼事也沒發生變化,它可能會更好用的功能,因爲:

  • 它使你的意圖明顯。
  • 更容易記錄。
  • 如果發生不可避免的情況,修改會更容易。
  • 無論順序如何工作。

(即使你只是把該函數的一個線分離或至少是註釋添加到分割!)


static String GetUsername(String value) 
{ 
    String result = ""; 
    String token = "Username="; 

    int index = value.IndexOf(token) + token.Length; 
    while (value[index] != ';') 
    { 
     result += value[index++]; 
     if (index > value.Length - 1) 
      break; 
    } 

    return result; 
} 
+0

我喜歡封裝這個「邏輯」的建議,但讓我們變成邪惡的:他的樣本並沒有以';'結尾。現在想象一下「用戶名=」部分到底是什麼,你的解決方案會發生什麼? –

+3

@Benjamin - 雖然不難處理這種情況;我認爲所有提出的解決方案都存在一些缺陷。例如,如果字符串中有兩個用戶名呢?會發生什麼?這個解決方案總是會選擇第一個。無論如何,我認爲這個微不足道的問題已經到了極點。 – 2010-02-22 19:30:18

+0

同意 - 以及+1 :) –

3

還不如不過採用分體式,就這麼簡單:

string input = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string username = Regex.Match(input, "Username=(?<username>.*?)(;|$)").Groups["username"].Value; 

在這種情況下,組可以按任意順序排列。

而且,如果你想獲得創意:

var answers = from tuple in input.Split(';') 
       where tuple.StartsWith("Username=") 
       select tuple.Split('=')[1]; 

username = answers.Count() > 0 ? answers.First() : string.Empty; 

有人可能會說的最後一塊具有更好的語義。

編輯:更新最後一塊處理輸入字符串沒有所需的元組。

+0

如果源字符串是'FirstName = ABC;用戶名= User1;姓名= XZY;密碼= 1234',將會失敗。使用'?'進行懶惰搜索:'用戶名=(?。*?);' –

+0

@Naeem Sarfraz:謝謝,你是對的。該死的貪婪的東西。另外,我更正了用戶名是字符串中最後一對的情況。現在REGEX是複雜的... –

1

這不是最短的......但可能是最快的之一。

string value = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
int offset = value.IndexOf("Username=") + 9; 
if (offset < 9) 
    throw new Exception("Username= not found in string"); 
int len = value.IndexOf(';', offset) - offset; 
if (len < 0) 
    len = value.Length - offset; 
string find = value.Substring(offset, len); 

...的if (len < 0)是是用戶名是在字符串的結束和不以分號結束。如果你想忽略情況下,你可以替換這個int offset線...

int offset = value.ToUpperInvariant().IndexOf("USERNAME=") + 9; 
+0

我知道「幻數」可以通過將「用戶名=」移動到一個變量,如令牌和使用token.Length來代替。 –

+0

隨時抱怨「例外」我不覺得有什麼更好的例子。 –

相關問題