In Swift 6:
/*
expRange.swift
xcrun --sdk macosx swiftc -Osize expRange.swift
Usage: expRange 1,3-7,10-20,24
Result: 1 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 24
*/
import Foundation
extension String {
var isNumber : Bool {
return !isEmpty && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
var isRange : Bool {
var thisSet = CharacterSet()
thisSet.insert(charactersIn: "0123456780-")
// return self.rangeOfCharacter(from: thisSet) != nil
return CharacterSet(charactersIn: self).isSubset(of: thisSet)
}
// return sequential string of white-space separated numbers including expanded ranges
func expand() -> String {
let sa = self.split(whereSeparator: { $0 == ","}).filter({ !$0.isEmpty })
var t = ""
for n in sa {
if !n.contains("-") {
guard String(n).isNumber else { continue }
t += n + " "
} else {
guard String(n).isRange else { continue }
let na = n.split(separator: "-").map { Int($0)! }
t += stride(from:na[0], through:na[1], by:1).compactMap { String($0)}.joined(separator: " ") + " "
}
}
return t
}
}
let args = CommandLine.arguments[1] as String
print(args.expand())
in Snobol4:
#!/usr/bin/env snobol4
* # Return range n1 .. n2
define('range(n1,n2)') :(range_end)
range range = range n1 ','; n1 = lt(n1,n2) n1 + 1 :s(range)
range rtab(1) . range :(return)
range_end
define('rangex(range)d1,d2')
num = ('-' | '') span('0123456789') :(rangex_end)
rangex range num . d1 '-' num . d2 = range(d1,d2) :s(rangex)
rangex = range :(return)
rangex_end
* # Test and display
output = rangex('-6,-3--1,3-5,7-11,14,15,17-20')
output = rangex(input)
end
expRange.sno
-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20
in Zsh shell:
#!/bin/zsh
: <<"COMMENT"
Usage: exp.zsh 1-3,4,5,7-10,12,15-20
COMMENT
typeset -a items=()
RANGE="$1"
# split the expansion string by commas into an array
items=( ${(s:,:)RANGE} )
# allows for sequential expansion of {n..m} sequences
setopt BRACE_CCL
for n in $items;
do
# check if n is just a number and not n-m
[[ $n =~ "^([0-9]+)$" ]] && outseq+="$n " && continue
# expand {n..m}
outseq+="$(print {${${n}:gs/-/..}}) "
done
print $outseq
unset items outseq
exit 0
in Perl:
#!/usr/bin/env perl
# expand sequence of numbers (e.g. 1-10,11,12,13-20)
# reference: https://rosettacode.org/wiki/Range_expansion#Perl
sub rangex {
map { /^(.*\d)-(.+)$/ ? $1..$2 : $_ } split /,/, shift
}
print join(' ', rangex($ARGV[0])), "\n";