HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Splitting a string into groups of up to 3 numbers, or one letter and up to 3 numbers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
groupsintonumbersandsplittingoneletterstring

Problem

There was an interesting idea brought up in The 2nd Monitor where one of our regulars was trying to split a bunch of strings into a specific format.

The format should be similar to the following:

A000
A00
900
90


Where A is any alphabetical letter, 0 is any number, and 9 is any number 1-9. No result string should begin with 0, it should always begin with A-Z or 1-9, and all alphabet characters will always be capitalized.

The input comes in a format similar to any of the following:

Input | Result
900A000 | 900, A000
900900 | 900, 900
90 | 90
99099 | 990, 99
A009A09 | A009, A09
A009A09900 | A009, A09, 900
A0990A09900 | A09, 90, A09, 900
A099090A09900 | A09, 90, 90, A09, 900
A09A990 | A09, A990
A990 | A990


The input will always parse to a valid group of strings.

The method:

public List SpecialSplit(string input)
{
    var result = new List();

    var currentString = new StringBuilder(4);
    for (var i = 0; i  0)
        {
            // Determine whether we're at constraints or not.
            var firstCharLetter = currentString[0] >= 'A' && currentString[0] = 'A' && c <= 'Z';

            if (mustSplit)
            {
                // If we must split our string, then verify we're not leaving an orphaned '0'.
                if (c == '0')
                {
                    // Go back a letter, take it out of the new string, and set our `c` to it.
                    i--;
                    currentString.Length--;
                    c = input[i];
                }

                // Add and clear the string to our result.
                result.Add(currentString.ToString());
                currentString.Clear();
            }
        }

        // Add our `c` to the string.
        currentString.Append(c);
    }

    // Add our string to the result.
    result.Add(currentString.ToString());

    return result;
}


And the test code:

```
var tests = new string

Solution

right ... "tempted to solve this with a regex" doesn't quite cut it. There is a regex that kinda sorta somewhat works, but I didn't get it to do exactly what I want.

Doesn't matter though, because I can make it do what I wanted, namely spit out the results directly as separate groups. Instead I got it to match the "last result" an:

private readonly Regex someNiceName = new Regex(@"^((?:[A-Z]\d|[1-9])\d{1,2})+$", RegexOptions.Compiled);

public List SpecialSplit(string input)
{
    if (input == "") 
    {
       return new List(); // base case for recursion
    }
    var match = someNiceName.Match(input);
    string last = match.Groups[1].Value;
    var precedessors = SpecialSplit(input.Substring(0, match.Groups[1].Index));
    precedessors.Add(last);
    return precedessors;
}


With a bit of luck we don't actually need this mess, but can rely on Captures instead:

public List SpecialSplit(string input) 
{
    var match = someNiceName.Match(input);
    var fullMatch = match.Groups[0];
    return fullMatch.Captures().Select(c => c.Value).ToList();
}


unfortunately I do not have C# available to check right now, but that might work better :)

Code Snippets

private readonly Regex someNiceName = new Regex(@"^((?:[A-Z]\d|[1-9])\d{1,2})+$", RegexOptions.Compiled);

public List<string> SpecialSplit(string input)
{
    if (input == "") 
    {
       return new List<string>(); // base case for recursion
    }
    var match = someNiceName.Match(input);
    string last = match.Groups[1].Value;
    var precedessors = SpecialSplit(input.Substring(0, match.Groups[1].Index));
    precedessors.Add(last);
    return precedessors;
}
public List<string> SpecialSplit(string input) 
{
    var match = someNiceName.Match(input);
    var fullMatch = match.Groups[0];
    return fullMatch.Captures().Select(c => c.Value).ToList();
}

Context

StackExchange Code Review Q#158329, answer score: 4

Revisions (0)

No revisions yet.