string format 开发者_运维百科is always like this "FirstName=ABC;LastName=XZY;Username=User1;Password=1234".
I need the only UserName value (which is 'User1' in this case). I wanna achieve this in minimum line of code using substring method (or something else).
Help?
For the sake of completeness, here is the Regex way of doing it. This will also work if the order changes.
// 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
Looks like a delimited string, so this would work:
string result = myString.Split(';')[2].Split('=')[1];
However, if someone changes the value pair order, this will break.
There are better ways about this, that will not break if the order changes, the number of parameters is different etc - such as the Regular Expression as Michael posted, or the Linq queries posted by a number of people.
Here is an alternative solution (not too different from others, but which I think is more straightforward) which will work regardless of order.
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]);
This method will work even if the value-pairs are given in a different order. It splits on the semicolon, finds the item with "Username", then returns what's after the equal sign.
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];
Least number of lines of code is not always the best metric, but you could do what you need with Regex.
While the split answers are 'ok' if nothing ever changes, it's probably better to use a function because:
- It makes your intentions clear.
- It is easier to document.
- It is easier to modify should the inevitable happen.
- Works regardless of order.
(Even if you just put the one line split in the function! or at the very least add a comment to the split.)
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;
}
Not as simple as using split, however:
string input = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234";
string username = Regex.Match(input, "Username=(?<username>.*?)(;|$)").Groups["username"].Value;
In this case, groups can be in any order.
And, if you like to get creative:
var answers = from tuple in input.Split(';')
where tuple.StartsWith("Username=")
select tuple.Split('=')[1];
username = answers.Count() > 0 ? answers.First() : string.Empty;
One might say the last piece has better semantics.
EDIT: Update the last piece to deal with input strings that doesn't have the required tuple.
string t = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234";
string name = t.Split(';')[2].Split('=')[1];
This isn't the shortest... but probably one of the fastest.
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);
... the if (len < 0)
is for is the Username is at the end of the string and doesn't end with a semicolon. If you want to ignore case you can replace the int offset
line with this...
int offset = value.ToUpperInvariant().IndexOf("USERNAME=") + 9;
精彩评论