Share via


Regex 101 Exercise I3 - Expand ranges in a string

I3 - Expand ranges in a string

Given a string like:

1,2,4,6-9,12,15-17,20

expand the ranges, so the final string is:

1,2,4,6,7,8,9,12,15,16,17,20

Comments

  • Anonymous
    January 09, 2006
    Stupid question time... are negative numbers disallowed? It's much more complicated to have to watch out for things like

    -8--6,-5,-3-2,4-7

  • Anonymous
    January 09, 2006
    But... why? That defeats the purpose of having the shorthand capabilities.

  • Anonymous
    January 09, 2006
    The comment has been removed

  • Anonymous
    January 09, 2006
    Well, here's two Perl solutions:
    http://www.geocities.com/mvaneerde/range-regex.pl.txt

    Don't see how to do it easily in a .NET regex...

    A specific justification does come to mind. If you're building a SQL string, this is valid..

    SELECT * FROM ThingsToDo WHERE ID IN (1,2,4,6,7,8,9,12,15,16,17,20)

    but this is not:
    SELECT * FROM ThingsToDo WHERE ID IN (1,2,4,6-9,12,15-17,20)

  • Anonymous
    January 09, 2006
    (does some research)

    OK, here's the C# equivalent:
    http://www.geocities.com/mvaneerde/range-regex.cs.txt

  • Anonymous
    January 09, 2006
    Well one obvious justification is in implementing page ranges. For example a function to print all pages in the range "1-5,7,9-10".

    I've implemented something like this via a custome Enumerator. Never thought to use a Regex, which sounds like a neat way to go about it.

  • Anonymous
    January 09, 2006
    This would be a handy place to use the "anonymous functions" feature of .Net 2.0 ...
    new MatchEvaluator( /* anonymous function here... */ )

  • Anonymous
    January 10, 2006
    In Python:

    [i for j in [range(int(s.split('-')[0]), int(s.split('-')[-1:][0])+1) for s in '1,2,4, 6-9,12,15-17,20'.split(',')] for i in j]

  • Anonymous
    January 10, 2006
    The comment has been removed

  • Anonymous
    January 10, 2006
    Windows:
    perl -e "$_ = shift; s/-/../g; $, = ','; print eval" 1,2,4,6-9,12,15-17,20

    Unix:
    perl -e '$_ = shift; s/-/../g; $, = ","; print eval' 1,2,4,6-9,12,15-17,20

  • Anonymous
    January 10, 2006
    Down to 63 characters, 21 of which are the data:

    Windows:
    echo 1,2,4,6-9,12,15-17,20|perl -ne"s/-/../g;$,=',';print eval"

    Unix:
    echo 1,2,4,6-9,12,15-17,20|perl -ne's/-/../g;$,=",";print eval'

  • Anonymous
    January 12, 2006
    As Maurits suggested earlier, seems the best way in .NET would be the MatchEvaluator. I couldn't come up with a portable one-liner since it looks as if the perl (?{ code }) thing doesn't seems to work.

    This doesn't handle negative,decreasing and other cases..

    string pattern = @"([0-9]+)-([0-9]+)";
    Regex regex = new Regex(pattern, RegexOptions.IgnorePatternWhitespace);
    string result = regex.Replace(@"1,2,4,6-9,12,15-17,20",
    (MatchEvaluator)delegate(Match tempmatch) {
    int s = int.Parse(tempmatch.Groups[1].Value);
    int e = int.Parse(tempmatch.Groups[2].Value);
    int i; StringBuilder sb = new StringBuilder();
    for (i = s; i < e; i++) { sb.Append(i); sb.Append(","); }
    return sb.Append(i).ToString(); }
    );

  • Anonymous
    January 12, 2006
    ups.. The (MatchEvaluator) cast is not needed.

  • Anonymous
    June 07, 2009
    PingBack from http://greenteafatburner.info/story.php?id=2318

  • Anonymous
    June 08, 2009
    PingBack from http://quickdietsite.info/story.php?id=1536

  • Anonymous
    June 17, 2009
    PingBack from http://pooltoysite.info/story.php?id=3314