How to fine tune a string using C #?

The string format always looks like this: "FirstName = ABC; LastName = XZY; Username = User1; Password = 1234".

I need a single UserName value (in this case, "User1"). I want to achieve this in a minimal line of code using the substring method (or something else).

reference

+6
substring c #
source share
9 answers

This method will work even if value pairs are specified in a different order. It breaks into a semicolon, finds an element with "Username", and then returns what is 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]; 
+4
source share

For completeness, there is a Regex way to do this. 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 
+15
source share

Looks like a delimited string, so this will work:

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

However, if someone changes the order of a pair of values, this will break.

We have the best ways that will not be violated, if the order changes, the number of parameters will be different, etc. - for example, a regular expression, as posted by Michael, or Linq queries sent by a number of people.

+12
source share

Here is an alternative solution (not too different from others, but which I think is simpler) that 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]); 
+7
source share

The smallest number of lines of code is not always the best metric, but you can do what you need with Regex.

+4
source share

While the answers to the division are β€œok”, if nothing changes, it is probably better to use a function because:

  • It makes your intentions understandable.
  • Easier to document.
  • It’s easier to change if the inevitable happens.
  • It works regardless of order.

(Even if you just split one line in a function! Or at 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; } 
+3
source share

Not as easy 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, the groups can be in any order.

And if you like to make an announcement:

 var answers = from tuple in input.Split(';') where tuple.StartsWith("Username=") select tuple.Split('=')[1]; username = answers.Count() > 0 ? answers.First() : string.Empty; 

We can say that the last fragment has the best semantics.

EDIT: Update the last fragment to process input strings that do not have the required tuple.

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

This is not 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); 

... if (len < 0) - this username is at the end of the line and does not end with a semicolon. If you want to ignore case, you can replace the string int offset with this ...

 int offset = value.ToUpperInvariant().IndexOf("USERNAME=") + 9; 
+1
source share

All Articles