Question

What's the easiest way to parse a string and extract a number and a letter? I have string that can be in the following format (number|letter or letter|number), i.e "10A", "B5", "C10", "1G", etc.

I need to extract the 2 parts, i.e. "10A" -> "10" and "A".

Update: Thanks to everyone for all the excellent answers

Was it helpful?

Solution

Easiest way is probably to use regular expressions.

((?<number>\d+)(?<letter>[a-zA-Z])|(?<letter>[a-zA-Z])(?<number>\d+))

You can then match it with your string and extract the value from the groups.

Match match = regex.Match("10A");
string letter = match.Groups["letter"].Value;
int number = int.Parse(match.Groups["number"].Value);

OTHER TIPS

The easiest and fastest is to use simple string operations. Use the IsDigit method to check where the letter is, and parse the rest of the string to a number:

char letter = str[0];
int index = 1;
if (Char.IsDigit(letter)) {
   letter = str[str.Length - 1];
   index = 0;
}
int number = int.Parse(str.Substring(index, str.Length - 1));
char letter = str.Single(c => char.IsLetter(c));
int num = int.Parse(new string(str.Where(c => char.IsDigit(c)).ToArray()));

This solution is not terribly strict (it would allow things like "5A2" and return 'A' and 52) but it may be fine for your purposes.

Just to be different:

string number = input.Trim("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray());
string letter = input.Trim("0123456789".ToCharArray());

Here is how I would approach this. You can step through this and put gc1["letter"], gc1["number"], gc2["letter"], and gc2["number"] in the watch window to see that it worked (step just past the last line of code here, of course).

The regular epxression will take either pattern requiring one or more letter and number in each case.

        Regex pattern = new Regex("^(?<letter>[a-zA-Z]+)(?<number>[0-9]+)|(?<number>[0-9]+)(?<letter>[a-zA-Z]+)$");
        string s1 = "12A";
        string s2 = "B45";
        Match m1 = pattern.Match(s1);
        Match m2 = pattern.Match(s2);
        GroupCollection gc1 = m1.Groups;
        GroupCollection gc2 = m2.Groups;

Using Sprache and some Linq kung-fu:

var tagParser =
    from a in Parse.Number.Or(Parse.Letter.Once().Text())
    from b in Parse.Letter.Once().Text().Or(Parse.Number)
    select char.IsDigit(a[0]) ?
           new{Number=a, Letter=b} : new{Number=b, Letter=a};

var tag1 = tagParser.Parse("10A");
var tag2 = tagParser.Parse("A10");

tag1.Letter; // should be A 
tag1.Number; // should be 10

tag2.Letter; // should be A
tag2.Number; // should be 10

/* Output:
   A
   10
   A
   10
 */
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top