<p>I was wondering if there is an open source library or algorithm that can expand a non-numeric range.  For example, if you have <code>1A</code> to <code>9A</code> you should get </p>

<pre><code>1A, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A.
</code></pre>

<p>I've tried Googling for this and the best I could come up with were Regex that would expand numerics with dashes (1-3 becoming 1,2,3).</p>

[{'answer_id': 45701, 'author': 'Gariig', 'author_id': 1210, 'author_profile': 'https://Stackoverflow.com/users/1210', 'pm_score': 0, 'selected': False, 'text': '<p>I was trying to leave it somewhat open because the number of possibilities is staggering.  I believe this one of those questions that could not be answered 100% here without going through a lot of technical detail about is considered a "good" or "bad" range.  I\'m just trying to find a jumping point for ideas on how other people have tackled this problem.  I was hoping that someone wrote a blog post explaining how they went about it solving this problem or created a whole library to handle this.</p>\n'}, {'answer_id': 45748, 'author': 'Ian', 'author_id': 4396, 'author_profile': 'https://Stackoverflow.com/users/4396', 'pm_score': 0, 'selected': False, 'text': "<p>I would say the first step in the solution will be to define how characters and numbers interact and form a sequence.  The given example isn't clear, as you would at least assume it to run 1A, 1B .... 8Y, 8Z, 9A  - that's assuming your input is restricted to decimal followed by a single character.</p>\n\n<p>If you can define a continuous sequence for characters and decimals, then you it will simply be a matter of some recursion / looping to generate part of that sequence.</p>\n\n<p>For example, you could assume that each character in the input is one of (1-9A-Z), therefore you could easily make that continuous by grabbing the decimal ascii value of the alpha characters and subtracting 55, in effect giving you the range (1-35)</p>\n"}, {'answer_id': 47126, 'author': 'Emperor XLII', 'author_id': 2495, 'author_profile': 'https://Stackoverflow.com/users/2495', 'pm_score': 0, 'selected': False, 'text': '<p>If we assume that the start and end ranges will follow the same alternating pattern, and limit the range of digits to <code>0-9</code> and <code>A-Z</code>, we can think of each group of digits as a component in a multi-dimensonal coordinate. For example, <code>1A</code> would correspond to the two-dimensional coordinate <code>(1,A)</code> (which is what Excel uses to label its two-dimensional grid of rows and columns); whereas <code>AA1BB2</code> would be a four-dimensional coordinate <code>(AA,1,BB,2)</code>.</p>\n\n<p>Because each component is independent, to expand the range between two coordinates we just return all combinations of the expansion of each component. Below is a quick implementation I cooked up this afternoon. It works for an arbitrary number of alternations of normal and alphabetic numbers, and handles large alphabetic ranges (i.e. from <code>AB</code> to <code>CDE</code>, not just <code>AB</code> to <code>CD</code>).</p>\n\n<p><strong>Note:</strong> This is intended as a rough draft of an actual implementation (I\'m taking off tomorrow, so it is even less polished than usual ;). All the usual caveats regarding error handling, robustness, (readability ;), etc, apply.</p>\n\n<pre><code>IEnumerable&lt;string&gt; ExpandRange( string start, string end ) {\n  // Split coordinates into component parts.\n  string[] startParts = GetRangeParts( start );\n  string[] endParts = GetRangeParts( end );\n\n  // Expand range between parts \n  //  (i.e. 1-&gt;3 becomes 1,2,3; A-&gt;C becomes A,B,C).\n  int length = startParts.Length;\n  int[] lengths = new int[length];\n  string[][] expandedParts = new string[length][];\n  for( int i = 0; i &lt; length; ++i ) {\n    expandedParts[i] = ExpandRangeParts( startParts[i], endParts[i] );\n    lengths[i] = expandedParts[i].Length;\n  }\n\n  // Return all combinations of expanded parts.\n  int[] indexes = new int[length];\n  do {\n      var sb = new StringBuilder( );\n      for( int i = 0; i &lt; length; ++i ) {\n        int partIndex = indexes[i];\n        sb.Append( expandedParts[i][partIndex] );\n      }\n      yield return sb.ToString( );\n  } while( IncrementIndexes( indexes, lengths ) );\n}\n\nreadonly Regex RangeRegex = new Regex( "([0-9]*)([A-Z]*)" );\nstring[] GetRangeParts( string range ) {\n  // Match all alternating digit-letter components of coordinate.\n  var matches = RangeRegex.Matches( range );\n  var parts =\n    from match in matches.Cast&lt;Match&gt;( )\n    from matchGroup in match.Groups.Cast&lt;Group&gt;( ).Skip( 1 )\n    let value = matchGroup.Value\n    where value.Length &gt; 0\n    select value;\n  return parts.ToArray( );\n}\n\nstring[] ExpandRangeParts( string startPart, string endPart ) {\n  int start, end;\n  Func&lt;int, string&gt; toString;\n\n  bool isNumeric = char.IsDigit( startPart, 0 );\n  if( isNumeric ) {\n    // Parse regular integers directly.\n    start = int.Parse( startPart );\n    end = int.Parse( endPart );\n    toString = ( i ) =&gt; i.ToString( );\n  }\n  else {\n    // Convert alphabetic numbers to integers for expansion,\n    //  then convert back for display.\n    start = AlphaNumberToInt( startPart );\n    end = AlphaNumberToInt( endPart );\n    toString = IntToAlphaNumber;\n  }\n\n  int count = end - start + 1;\n  return Enumerable.Range( start, count )\n    .Select( toString )\n    .Where( s =&gt; s.Length &gt; 0 )\n    .ToArray( );\n}\n\nbool IncrementIndexes( int[] indexes, int[] lengths ) {\n  // Increment indexes from right to left (i.e. Arabic numeral order).\n  bool carry = true;\n  for( int i = lengths.Length; carry &amp;&amp; i &gt; 0; --i ) {\n    int index = i - 1;\n    int incrementedValue = (indexes[index] + 1) % lengths[index];\n    indexes[index] = incrementedValue;\n    carry = (incrementedValue == 0);\n  }\n  return !carry;\n}\n\n// Alphabetic numbers are 1-based (i.e. A = 1, AA = 11, etc, mod base-26).\nconst char AlphaDigitZero = (char)(\'A\' - 1);\nconst int AlphaNumberBase = \'Z\' - AlphaDigitZero + 1;\nint AlphaNumberToInt( string number ) {\n  int sum = 0;\n  int place = 1;\n  foreach( char c in number.Cast&lt;char&gt;( ).Reverse( ) ) {\n    int digit = c - AlphaDigitZero;\n    sum += digit * place;\n    place *= AlphaNumberBase;\n  }\n  return sum;\n}\n\nstring IntToAlphaNumber( int number ) {\n  List&lt;char&gt; digits = new List&lt;char&gt;( );\n  while( number &gt; 0 ) {\n    int digit = number % AlphaNumberBase;\n    if( digit == 0 )  // Compensate for 1-based alphabetic numbers.\n      return "";\n\n    char c = (char)(AlphaDigitZero + digit);\n    digits.Add( c );\n    number /= AlphaNumberBase;\n  }\n\n  digits.Reverse( );\n  return new string( digits.ToArray( ) );\n}\n</code></pre>\n'}, {'answer_id': 47373, 'author': 'mweerden', 'author_id': 4285, 'author_profile': 'https://Stackoverflow.com/users/4285', 'pm_score': 1, 'selected': False, 'text': '<p>As noted by others, it would be useful to be more specific. I don\'t think you can expect there to be a library that will generate ranges according to any arbitrary order on string you can come up with.</p>\n\n<p>If you can simply define what the successor of any given string is, then the solutions is quite easy. That is, if you have a successor function <code>S</code> on strings (e.g. with <code>S(\'3A\') = \'4A\'</code>), then something like the following can be used:</p>\n\n<pre><code>s = initial_string\nwhile s != final_string do\n  output s\n  s = S(s)\noutput s\n</code></pre>\n\n<p>Something I have used in the past to generate all strings of a given length <code>l</code> and with given range <code>b</code> to <code>e</code> of characters, is the following piece of (pseudo-)code. It can be easily adapted to a wide range of variations.</p>\n\n<pre><code>// initialise s with b at every position\nfor i in [0..l) do\n  s[i] = b\ndone = false\nwhile not done do\n  output s\n  j = 0\n  // if s[j] is e, reset it to b and "add carry"\n  while j &lt; l and s[j] == e do\n    s[j] = b\n    j = j + 1\n    if j == l then\n      done = true\n  if not done then\n    s[j] = s[j] + 1\n</code></pre>\n\n<p>For example, to start at a specific string you need only the change the initialisation. To set the end you only need to change the behaviour for the inner while to separately handle position <code>l</code> (limiting to the character in the end string on that position and if reached decrementing <code>l</code>).</p>\n'}]
['https://Stackoverflow.com/questions/45642', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1210/']