Public Structure Range
Private _first As Integer
Public Property First() As Integer
Get
Return _first
End Get
Set(ByVal value As Integer)
_first = value
End Set
End Property
Private _last As Integer
Public Property Last() As Integer
Get
Return _last
End Get
Set(ByVal value As Integer)
_last = value
End Set
End Property
Public ReadOnly Property Count() As Integer
Get
Return Last - First + 1
End Get
End Property
Private _delim As String
Public Property RangeDelimiter() As String
Get
If _delim Is Nothing Then
Return "-"
Else
Return _delim
End If
End Get
Set(ByVal value As String)
_delim = value
End Set
End Property
Public Sub New(ByVal first As Integer, ByVal last As Integer, Optional ByVal rangeDelimiter As String = "-")
Me.First = first
Me.Last = last
Me.RangeDelimiter = rangeDelimiter
End Sub
Public Shared Function ParseRanges(ByVal input As String, Optional ByVal rangeDelimiter As String = "-") As Range()
Dim numbers As New List(Of Integer)
For Each m As Match In Regex.Matches(input, "\d+")
numbers.Add(CInt(m.Value))
Next
numbers.Sort()
Dim ranges As New List(Of Range)
Dim r As New Range(numbers(0), numbers(0), rangeDelimiter)
For i As Integer = 1 To numbers.Count - 1
If numbers(i) - numbers(i - 1) = 1 Then
r.Last = numbers(i)
Else
ranges.Add(r)
r = New Range(numbers(i), numbers(i), rangeDelimiter)
End If
If i = numbers.Count - 1 Then
ranges.Add(r)
End If
Next
Return ranges.ToArray
End Function
Public Overrides Function ToString() As String
Select Case Me.Count
Case 1
Return Me.First.ToString
Case 2
Return String.Format("{0},{1}", Me.First, Me.Last)
Case Else
Return String.Format("{0}{1}{2}", Me.First, Me.RangeDelimiter, Me.Last)
End Select
End Function
Public Shared Function RangesToString(ByVal ranges() As Range) As String
Dim rs() As String = Array.ConvertAll(ranges, Function(r As Range) r.ToString)
Return String.Join(",", rs)
End Function
End Structure