字符串格式總是像這樣「FirstName = ABC; LastName = XZY;用戶名= User1;密碼= 1234」。如何從一個字符串使用C#子字符串?
我需要唯一的UserName值(在這種情況下是'User1')。我想在使用子字符串方法(或其他)的最小代碼行中實現這一點。
幫助?
字符串格式總是像這樣「FirstName = ABC; LastName = XZY;用戶名= User1;密碼= 1234」。如何從一個字符串使用C#子字符串?
我需要唯一的UserName值(在這種情況下是'User1')。我想在使用子字符串方法(或其他)的最小代碼行中實現這一點。
幫助?
即使值對以不同的順序給出,該方法仍然有效。它在分號上分開,用「用戶名」找到該項目,然後返回等號後面的內容。
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];
看起來像一個分隔的字符串,所以這會工作:
string result = myString.Split(';')[2].Split('=')[1];
但是,如果有人更改值對訂單,這將打破。
有更好的方法可以解決這個問題,如果順序改變,參數的數量不同等等 - 比如Michael發佈的正則表達式,或者許多人發佈的Linq查詢。
打我吧:( –
我很欣賞你試圖儘可能縮短它,但我認爲我們有最近看到的最醜陋的代碼的贏家(沒有任何意圖!) – brian
我wouldn不要說它有史以來最醜陋的代碼,但用戶得到了他想要的東西..... –
string t = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234";
string name = t.Split(';')[2].Split('=')[1];
這裏是一個替代的解決方案(從別人不太一樣,但我認爲這是更簡單),無論其將工作秩序。
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]);
當字符串沒有「用戶名」時失敗。 –
如果可能沒有用戶名,可以在'.Single()'之前添加'.Select(pair => pair [1])'並將'.Single()'改爲'.SingleOrDefault()'。那麼如果沒有用戶名,你就會得到空值。 –
爲了完整起見,這裏是正則表達式的方法。如果訂單改變,這也將起作用。
// 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
這實際上是應用正則表達式的好地方。好東西。 –
雖然分裂的答案是「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;
}
我喜歡封裝這個「邏輯」的建議,但讓我們變成邪惡的:他的樣本並沒有以';'結尾。現在想象一下「用戶名=」部分到底是什麼,你的解決方案會發生什麼? –
@Benjamin - 雖然不難處理這種情況;我認爲所有提出的解決方案都存在一些缺陷。例如,如果字符串中有兩個用戶名呢?會發生什麼?這個解決方案總是會選擇第一個。無論如何,我認爲這個微不足道的問題已經到了極點。 – 2010-02-22 19:30:18
同意 - 以及+1 :) –
還不如不過採用分體式,就這麼簡單:
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;
有人可能會說的最後一塊具有更好的語義。
編輯:更新最後一塊處理輸入字符串沒有所需的元組。
如果源字符串是'FirstName = ABC;用戶名= User1;姓名= XZY;密碼= 1234',將會失敗。使用'?'進行懶惰搜索:'用戶名=(?
@Naeem Sarfraz:謝謝,你是對的。該死的貪婪的東西。另外,我更正了用戶名是字符串中最後一對的情況。現在REGEX是複雜的... –
這不是最短的......但可能是最快的之一。
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;
我知道「幻數」可以通過將「用戶名=」移動到一個變量,如令牌和使用token.Length來代替。 –
隨時抱怨「例外」我不覺得有什麼更好的例子。 –
當一個問題有非常明確的答案像這樣它總是一件有趣的我看有多少不同的解決方案多所社區提供。 –
有一點需要注意:輸入字符串有一個名爲「User ** n ** name」的字段。然後您要求「User ** N ** ame」字段。解析字符串時要小心套話。當然有處理這個問題的方法。 –