Brace expansion using ranges: Difference between revisions

→‎{{header|jq}}: right-most-first
(→‎Task: Updated output to show additional example. (Required to resolve ambiguity identified on Discussion page by Nigel Galloway))
(→‎{{header|jq}}: right-most-first)
 
(11 intermediate revisions by 7 users not shown)
Line 1:
{{draft task}}{{clarified-review}}
 
;Task
{{task heading}}
 
Write and test a function which expands one or more Unix-style '''numeric and alphabetic range braces''' embedded in a larger string.<br><br>
Line 54:
{{task heading|Tests}}
 
Generate and display here the expansion of (at least) each of the nineten example lines shown abovebelow.
 
The JavaScript implementation below uses parser combinators, aiming to encode a more or less full and legible description of the <pre><PREAMBLE><AMBLE><POSTSCRIPT></pre> range brace grammar, but you should use any resource that suggests itself in your language, including parser libraries.
Line 111:
* &nbsp; [[Range_expansion|range expansion]]
<br><br>
 
=={{header|11l}}==
{{trans|Nim}}
 
<langsyntaxhighlight lang="11l">F intFromString(s) -> Int?
X.try
R Int(s)
Line 219 ⟶ 218:
V res = rangeExpand(s)
print(res.join("\n "))
print()</langsyntaxhighlight>
 
{{out}}
Line 275 ⟶ 274:
 
</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">Brace_expansion_using_ranges(line){
needle := "^.*\K{(?P<Start>[^{}]+?)\..(?P<End>[^{}]+?)(?:\..(?P<Incr>[^{}]+?))?}"
while true
{
while pos := RegExMatch(line, needle, m, A_Index=1?1:pos+StrLen(m))
{
char := false, step := "", output := ""
reverse := InStr(mIncr, "-") ? true : false
if mStart is number
pad1 := pad(mStart), pad2 := pad(mEnd), pad := StrLen(pad1)>=StrLen(pad2) ? pad1 : pad2
else
mStart := Ord(mStart), mEnd := Ord(mEnd), char := true
mIncr := (mIncr?Abs(mIncr):1) * (mStart>mEnd?-1:1)
loop % Abs((mStart-mEnd)/mIncr) + 1
{
step := mStart + (A_Index-1) * mIncr
step := pad <> "" ? SubStr(pad . step, 1-StrLen(pad)) : step
step := char ? Chr(step) : step
Rep := StrReplace(line, m, step)
output := reverse ? rep "`n" output : output .= Rep "`n"
}
output := Trim(Output, "`n")
}
if RegExMatch(output, needle)
line := output
else
break
}
return output ? output : line
}
pad(num){
if RegExMatch(num, "`am)^(0+)(?=[1-9]|0$)", m)
loop % StrLen(num)
pad .= "0"
return pad
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">data=
(
simpleNumberRising{1..3}.txt
simpleAlphaDescending-{Z..X}.txt
steppedDownAndPadded-{10..00..5}.txt
minusSignFlipsSequence {030..20..-5}.txt
reverseSteppedNumberRising{1..6..-2}.txt
combined-{Q..P}{2..1}.txt
emoji{🌵..🌶}{🌽..🌾}etc
li{teral
rangeless{}empty
rangeless{random}string
)
for i, line in StrSplit(data, "`n", "`r")
result .= line " ->`n" RegExReplace(Brace_expansion_using_ranges(line), "`am)^", "`t") "`n`n"
 
MsgBox, 262144, , % result
return</syntaxhighlight>
{{out}}
<pre>simpleNumberRising{1..3}.txt ->
simpleNumberRising1.txt
simpleNumberRising2.txt
simpleNumberRising3.txt
 
simpleAlphaDescending-{Z..X}.txt ->
simpleAlphaDescending-Z.txt
simpleAlphaDescending-Y.txt
simpleAlphaDescending-X.txt
 
steppedDownAndPadded-{10..00..5}.txt ->
steppedDownAndPadded-10.txt
steppedDownAndPadded-05.txt
steppedDownAndPadded-00.txt
 
minusSignFlipsSequence {030..20..-5}.txt ->
minusSignFlipsSequence 020.txt
minusSignFlipsSequence 025.txt
minusSignFlipsSequence 030.txt
 
reverseSteppedNumberRising{1..6..-2}.txt ->
reverseSteppedNumberRising5.txt
reverseSteppedNumberRising3.txt
reverseSteppedNumberRising1.txt
 
combined-{Q..P}{2..1}.txt ->
combined-Q2.txt
combined-Q1.txt
combined-P2.txt
combined-P1.txt
 
emoji{🌵..🌶}{🌽..🌾}etc ->
emoji🌵🌽etc
emoji🌵🌾etc
emoji🌶🌽etc
emoji🌶🌾etc
 
li{teral ->
li{teral
 
rangeless{}empty ->
rangeless{}empty
 
rangeless{random}string ->
rangeless{random}string</pre>
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
// Brace expansion using ranges. Nigel Galloway: October 6th., 2021
let fUC, fUR=System.Text.Rune.GetUnicodeCategory,(fun n->System.Text.Rune.GetRuneAt(n,0))
Line 296 ⟶ 397:
let tests=["simpleNumberRising{1..3}.txt";"steppedNumberRising{1..6..2}.txt";"reverseSteppedNumberRising{1..6..-2}.txt";"steppedNumberDescending{20..9..2}.txt";"simpleAlphaDescending-{Z..X}.txt";"steppedDownAndPadded-{10..00..5}.txt";"minusSignFlipsSequence {030..20..-5}.txt";"combined-{Q..P}{2..1}.txt";"emoji{🌵..🌶}{🌽..🌾}etc";"li{teral";"rangeless{random}string";"rangeless{}empty";"steppedAlphaDescending-{Z..M..2}.txt";"reversedSteppedAlphaDescending-{Z..M..-2}.txt"]
tests|>List.iter(fun g->printfn $"%s{g}->"; for n in expBraces g do printfn $" %s{n}")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 365 ⟶ 466:
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 373 ⟶ 474:
"unicode/utf8"
)
 
func sign(n int) int {
switch {
case n < 0:
return -1
case n > 0:
return 1
}
return 0
}
 
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
 
func parseRange(r string) []string {
Line 424 ⟶ 542:
if n3 < 0 {
asc = !asc
n1, n2t := n2, n1
d := abs(n1-n2) % (-n3)
n1 = n2 - d*sign(n2-n1)
n2 = t
n3 = -n3
}
Line 489 ⟶ 610:
"steppedDownAndPadded-{10..00..5}.txt",
"minusSignFlipsSequence {030..20..-5}.txt",
"reverseSteppedNumberRising{1..6..-2}.txt",
"combined-{Q..P}{2..1}.txt",
"emoji{🌵..🌶}{🌽..🌾}etc",
Line 497 ⟶ 619:
"steppedAlphaRising{P..Z..2}.txt",
"stops after endpoint-{02..10..3}.txt",
"steppedNumberRising{1..6..2}.txt",
"steppedNumberDescending{20..9..2}",
"steppedAlphaDescending-{Z..M..2}.txt",
"reversedSteppedAlphaDescending-{Z..M..-2}.txt",
}
for _, s := range examples {
Line 504 ⟶ 630:
fmt.Println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 510 ⟶ 636:
Same as Wren entry.
</pre>
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">(() => {
"use strict";
 
Line 527 ⟶ 652:
 
return 0 < expansions.length ? (() => {
const [parsed, residue] = Array.from(expansions[0];
expansions[0]
);
 
return suffixAdd(
Line 584 ⟶ 707:
];
 
return tests.map(s => {
s => {const
constexpanded = braceExpandWithRange(s)
expanded = braceExpandWithRange.join(s"\n\t");
.join("\n\t");
 
return `${s} -> \n\t${expanded}`;
})
)
.join("\n\n");
};
Line 773 ⟶ 894:
p => Parser(
s => parse(pf)(s).flatMap(
vr([v, r]) => parse(
fmapP(vr[0]v)(p)
)(vr[1]r)
)
);
Line 804 ⟶ 925:
f => Parser(
s => parse(p)(s).flatMap(
tpl([x, r]) => parse(f(tpl[0]x))(tpl[1]r)
)
);
Line 847 ⟶ 968:
p => Parser(
s => parse(p)(s).flatMap(
vr => Tuplefirst(f(vr[0]))(vr[1])
)
);
Line 855 ⟶ 976:
const item = () =>
// A single character.
Parser(s => {
sconst =>[h, 0...t] <= s.length ? [;
 
Tuple(s[0])(
return Boolean(h) ? s.slice(1)[
Tuple(h)(t)
] : [];
});
 
 
Line 922 ⟶ 1,043:
// Any character for which the
// given predicate returns true.
Parser(s => {
sconst =>[h, 0...t] <= s.length ? (;
 
test(s[0]) ? [
return Boolean(h) ? Tuple(s[0])(s.slice(1))
test(h) ? [
Tuple(h)(t)
] : []
) : [];
});
 
// sequenceP :: [Parser a] -> Parser [a]
Line 937 ⟶ 1,060:
s => ps.reduce(
(a, q) => a.flatMap(
vr([v, r]) => parse(q)(snd(vr)r).flatMap(
first(xs => fst(vr)v.concat(xs))
)
),
Line 980 ⟶ 1,103:
"0": a,
"1": b,
length: 2,
*[Symbol.iterator]() {
for (const k in this) {
if (!isNaN(k)) {
yield this[k];
}
}
}
});
 
 
// abs :: Num -> Num
Line 1,019 ⟶ 1,150:
 
// concat :: [[a]] -> [a]
//const concat ::= [String]xs -=> String
const concat = xs => .flat(1);
ys => 0 < ys.length ? (
ys.every(Array.isArray) ? (
[]
) : ""
).concat(...ys) : ys
)(list(xs));
 
 
Line 1,059 ⟶ 1,184:
// A simple function lifted to one which applies
// to a tuple, transforming only its first item.
xy([x, y]) => Tuple(f(xy[0]x))(y);
xy[1]
);
 
 
Line 1,071 ⟶ 1,194:
(a, b) => op(b, a)
) : (x => y => op(y)(x));
 
 
// fst :: (a, b) -> a
const fst = tpl =>
// First member of a pair.
tpl[0];
 
 
Line 1,109 ⟶ 1,226:
s.padStart(n, c)
) : s;
 
 
// list :: StringOrArrayLike b => b -> [a]
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
) : Array.from(xs || []);
 
 
Line 1,179 ⟶ 1,287:
const reverse = xs =>
xs.slice(0).reverse();
 
 
// snd :: (a, b) -> b
const snd = tpl =>
// Second member of a pair.
tpl[1];
 
 
Line 1,202 ⟶ 1,304:
return "number" !== t ? (
(() => {
const [i, mx] = [x, maxBound(x)].map(fromEnum);
fromEnum
);
 
return i < mx ? (
Line 1,241 ⟶ 1,345:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>simpleNumberRising{1..3}.txt ->
Line 1,288 ⟶ 1,392:
rangeless{random}string ->
rangeless{random}string</pre>
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
This implementation relies on "reluctant" regex parsing.
 
Range expressions of the form {x..y}, where x and y are single
characters, are allowed, even if exactly one of them is a digit.
 
When expanding an expression with more than one range, the program
as given below produces an ordering
based on expansion of the left-most range first.
A trivial change in two places is sufficient to produce the alternative ordering.
<syntaxhighlight lang="jq">
# Left-pad with 0s
def lpad($len): tostring | ($len - length) as $l | ("0" * $l) + .;
 
def expand:
# The key to success here is reluctance (".*?")
def cap:
capture("(?<head>^.*?)[{](?<from>[0-9]+|.)[.][.](?<to>[0-9]+|.)"
+ "([.][.](?<sign>-)?(?<increment>[0-9]))?[}](?<tail>.*)$");
 
def ton: if . == null then . else tonumber end;
 
# Produce a stream of integers, handling implicit descent.
# $i and $j should be integers.
# If $i and $j are distinct, then expand($i;$j;null;null) will include both,
# otherwise just $i.
def expand($i; $j; $sign; $increment):
(if $increment == null then 1 else $increment end) as $inc
| if $sign == null
then if $i <= $j
then range($i; $j + 1; $inc)
else range($i; $j - 1; - $inc)
end
else [expand($i; $j; null; $increment)] | reverse[]
end ;
 
# Produce a stream of single characters, handling implicit descent
def explode($x; $y; $sign; $increment):
($x|explode[0]) as $x
| ($y|explode[0]) as $y
| expand($x; $y; $sign; $increment)
| [.] | implode;
 
# The number of leading 0s of the input string
def leadingZeros: match("^0*") | .string | length;
def padding($x; $y):
($x | leadingZeros) as $a
| ($y | leadingZeros) as $b
| [if $a > 0 then ($x|length) else 0 end,
if $b > 0 then ($y|length) else 0 end]
| max;
( cap as $c
| if ($c.from|test("[0-9]+")) and ($c.to|test("[0-9]+"))
then padding($c.from; $c.to) as $padding
| $c.head
+ ( expand($c.from|tonumber;
$c.to|tonumber;
$c.sign;
$c.increment | ton) | lpad($padding))
+ ($c.tail | expand)
elif ($c.from|length == 1) and ($c.to|length == 1)
then $c.head + explode($c.from; $c.to; $c.sign; $c.increment|ton)
+ ($c.tail | expand)
else ""
end )
// . ;
 
def examples:
"simpleNumberRising{1..3}.txt",
"simpleAlphaDescending-{Z..X}.txt",
"steppedDownAndPadded-{10..00..5}.txt",
"minusSignFlipsSequence {030..20..-5}.txt",
"reverseSteppedNumberRising{1..6..-2}.txt",
"combined-{Q..P}{2..1}.txt",
"emoji{🌵..🌶}{🌽..🌾}etc",
"li{teral",
"rangeless{}empty",
"rangeless{random}string",
"mixedNumberAlpha{5..k}",
"steppedAlphaRising{P..Z..2}.txt",
"stops after endpoint-{02..10..3}.txt",
"steppedNumberRising{1..6..2}.txt",
"steppedNumberDescending{20..9..2}",
"steppedAlphaDescending-{Z..M..2}.txt",
"reversedSteppedAlphaDescending-{Z..M..-2}.txt"
;
 
examples
| "\(.) ->",
" \(expand)", ""
</syntaxhighlight>
{{output}}
<pre style="height:20lh;overflow:auto>
simpleNumberRising{1..3}.txt ->
simpleNumberRising1.txt
simpleNumberRising2.txt
simpleNumberRising3.txt
 
simpleAlphaDescending-{Z..X}.txt ->
simpleAlphaDescending-Z.txt
simpleAlphaDescending-Y.txt
simpleAlphaDescending-X.txt
 
steppedDownAndPadded-{10..00..5}.txt ->
steppedDownAndPadded-10.txt
steppedDownAndPadded-05.txt
steppedDownAndPadded-00.txt
 
minusSignFlipsSequence {030..20..-5}.txt ->
minusSignFlipsSequence 020.txt
minusSignFlipsSequence 025.txt
minusSignFlipsSequence 030.txt
 
reverseSteppedNumberRising{1..6..-2}.txt ->
reverseSteppedNumberRising5.txt
reverseSteppedNumberRising3.txt
reverseSteppedNumberRising1.txt
 
combined-{Q..P}{2..1}.txt ->
combined-Q2.txt
combined-P2.txt
combined-Q1.txt
combined-P1.txt
 
emoji{🌵..🌶}{🌽..🌾}etc ->
emoji🌵🌽etc
emoji🌶🌽etc
emoji🌵🌾etc
emoji🌶🌾etc
 
li{teral ->
li{teral
 
rangeless{}empty ->
rangeless{}empty
 
rangeless{random}string ->
rangeless{random}string
 
mixedNumberAlpha{5..k} ->
mixedNumberAlpha5
mixedNumberAlpha6
mixedNumberAlpha7
mixedNumberAlpha8
mixedNumberAlpha9
mixedNumberAlpha:
mixedNumberAlpha;
mixedNumberAlpha<
mixedNumberAlpha=
mixedNumberAlpha>
mixedNumberAlpha?
mixedNumberAlpha@
mixedNumberAlphaA
mixedNumberAlphaB
mixedNumberAlphaC
mixedNumberAlphaD
mixedNumberAlphaE
mixedNumberAlphaF
mixedNumberAlphaG
mixedNumberAlphaH
mixedNumberAlphaI
mixedNumberAlphaJ
mixedNumberAlphaK
mixedNumberAlphaL
mixedNumberAlphaM
mixedNumberAlphaN
mixedNumberAlphaO
mixedNumberAlphaP
mixedNumberAlphaQ
mixedNumberAlphaR
mixedNumberAlphaS
mixedNumberAlphaT
mixedNumberAlphaU
mixedNumberAlphaV
mixedNumberAlphaW
mixedNumberAlphaX
mixedNumberAlphaY
mixedNumberAlphaZ
mixedNumberAlpha[
mixedNumberAlpha\
mixedNumberAlpha]
mixedNumberAlpha^
mixedNumberAlpha_
mixedNumberAlpha`
mixedNumberAlphaa
mixedNumberAlphab
mixedNumberAlphac
mixedNumberAlphad
mixedNumberAlphae
mixedNumberAlphaf
mixedNumberAlphag
mixedNumberAlphah
mixedNumberAlphai
mixedNumberAlphaj
mixedNumberAlphak
 
steppedAlphaRising{P..Z..2}.txt ->
steppedAlphaRisingP.txt
steppedAlphaRisingR.txt
steppedAlphaRisingT.txt
steppedAlphaRisingV.txt
steppedAlphaRisingX.txt
steppedAlphaRisingZ.txt
 
stops after endpoint-{02..10..3}.txt ->
stops after endpoint-02.txt
stops after endpoint-05.txt
stops after endpoint-08.txt
 
steppedNumberRising{1..6..2}.txt ->
steppedNumberRising1.txt
steppedNumberRising3.txt
steppedNumberRising5.txt
 
steppedNumberDescending{20..9..2} ->
steppedNumberDescending20
steppedNumberDescending18
steppedNumberDescending16
steppedNumberDescending14
steppedNumberDescending12
steppedNumberDescending10
 
steppedAlphaDescending-{Z..M..2}.txt ->
steppedAlphaDescending-Z.txt
steppedAlphaDescending-X.txt
steppedAlphaDescending-V.txt
steppedAlphaDescending-T.txt
steppedAlphaDescending-R.txt
steppedAlphaDescending-P.txt
steppedAlphaDescending-N.txt
 
reversedSteppedAlphaDescending-{Z..M..-2}.txt ->
reversedSteppedAlphaDescending-N.txt
reversedSteppedAlphaDescending-P.txt
reversedSteppedAlphaDescending-R.txt
reversedSteppedAlphaDescending-T.txt
reversedSteppedAlphaDescending-V.txt
reversedSteppedAlphaDescending-X.txt
reversedSteppedAlphaDescending-Z.txt
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">padzeros(str) = (len = length(str)) > 1 && str[1] == '0' ? len : 0
 
function ranged(str)
Line 1,331 ⟶ 1,681:
println(test, "->\n", [" " * x * "\n" for x in splatrange(test)]...)
end
</langsyntaxhighlight>{{out}}
<pre>
simpleNumberRising{1..3}.txt->
Line 1,393 ⟶ 1,743:
=={{header|Nim}}==
{{trans|Wren}}
<langsyntaxhighlight Nimlang="nim">import options, strutils, unicode
 
 
Line 1,507 ⟶ 1,857:
stdout.write res.join("\n ")
echo '\n'
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,567 ⟶ 1,917:
stops after endpoint-08.txt
</pre>
 
=={{header|Phix}}==
{{trans|Wren}}
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0.8.2"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (is_integer() is new, plus "==sign(inc)" found me a long-buried compiler bug)</span>
Line 1,687 ⟶ 2,036:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s -&gt;\n %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">range_expand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n "</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
Note that, as usual, unicode output does not look good on a windows console for tests 6 & 7 (linux output shown)
Line 1,739 ⟶ 2,088:
stops after endpoint-08.txt
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">"""Brace expansion using ranges. Requires Python >= 3.6.
<lang python>
"""Brace range expansion. Requires Python >=3.6.
 
Here we use regular expressions for parsing and take an object orientated approach
to expansion of range expressions.
 
This implementation supports stepped ordinal range expressions.
NOTE: With my current version of bash (GNU bash, version 5.0.3(1)-release), a ``-``
or ``+`` character in front of a `step` has no effect. This implementation reverses
the range if a ``-`` immediately precedes a step, and does not recognize range
expressions that use a ``+``.
 
NOTE: This implementation supports stepped ordinal range expressions.
"""
 
Line 1,871 ⟶ 2,213:
# A negative step means we reverse the range.
start, stop = stop, start
 
step = abs(step)
if start < stop:
step = abs(step)
else:
start -= 1
stop -= 1
 
elif start > stop:
Line 1,917 ⟶ 2,264:
cases = [
r"simpleNumberRising{1..3}.txt",
r"steppedNumberRising{1..6..2}.txt",
r"steppedNumberDescending{20..9..2}.txt",
r"simpleAlphaDescending-{Z..X}.txt",
r"steppedDownAndPadded-{10..00..5}.txt",
r"minusSignFlipsSequence {030..20..-5}.txt",
r"reverseSteppedNumberRising{1..6..-2}.txt",
r"combined-{Q..P}{2..1}.txt",
r"emoji{🌵..🌶}{🌽..🌾}etc",
r"li{teral",
r"rangeless{random}string",
r"rangeless{}empty",
r"rangeless{random}string",
# Extra examples, not from the task description.
r"steppedNumberRising{1..6..2}.txt",
r"steppedNumberDescending{20..9..2}.txt",
r"steppedAlphaDescending-{Z..M..2}.txt",
r"reverseSteppedAlphaRising{A..F..-2}.txt",
r"reversedSteppedAlphaDescending-{Z..M..-2}.txt",
]
Line 1,943 ⟶ 2,293:
if __name__ == "__main__":
examples()
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,951 ⟶ 2,301:
simpleNumberRising2.txt
simpleNumberRising3.txt
 
steppedNumberRising{1..6..2}.txt ->
steppedNumberRising1.txt
steppedNumberRising3.txt
steppedNumberRising5.txt
 
steppedNumberDescending{20..9..2}.txt ->
steppedNumberDescending20.txt
steppedNumberDescending18.txt
steppedNumberDescending16.txt
steppedNumberDescending14.txt
steppedNumberDescending12.txt
steppedNumberDescending10.txt
 
simpleAlphaDescending-{Z..X}.txt ->
Line 1,979 ⟶ 2,316:
minusSignFlipsSequence 025.txt
minusSignFlipsSequence 030.txt
 
reverseSteppedNumberRising{1..6..-2}.txt ->
reverseSteppedNumberRising5.txt
reverseSteppedNumberRising3.txt
reverseSteppedNumberRising1.txt
 
combined-{Q..P}{2..1}.txt ->
Line 1,994 ⟶ 2,336:
li{teral ->
li{teral
 
rangeless{}empty ->
rangeless{}empty
 
rangeless{random}string ->
rangeless{random}string
 
steppedNumberRising{1..6..2}.txt ->
rangeless{}empty ->
steppedNumberRising1.txt
rangeless{}empty
steppedNumberRising3.txt
steppedNumberRising5.txt
 
steppedNumberDescending{20..9..2}.txt ->
steppedNumberDescending20.txt
steppedNumberDescending18.txt
steppedNumberDescending16.txt
steppedNumberDescending14.txt
steppedNumberDescending12.txt
steppedNumberDescending10.txt
 
steppedAlphaDescending-{Z..M..2}.txt ->
Line 2,009 ⟶ 2,364:
steppedAlphaDescending-P.txt
steppedAlphaDescending-N.txt
 
reverseSteppedAlphaRising{A..F..-2}.txt ->
reverseSteppedAlphaRisingE.txt
reverseSteppedAlphaRisingC.txt
reverseSteppedAlphaRisingA.txt
 
reversedSteppedAlphaDescending-{Z..M..-2}.txt ->
Line 2,019 ⟶ 2,379:
reversedSteppedAlphaDescending-Y.txt
</pre>
 
=={{header|Raku}}==
{{works with|Rakudo|2020.08.1}}
Also implements some of the string list functions described on the bash-hackers page.
 
<syntaxhighlight lang="raku" perl6line>my $range = rx/ '{' $<start> = <-[.]>+? '..' $<end> = <-[.]>+? ['..' $<incr> = ['-'?\d+] ]? '}' /;
my $list = rx/ ^ $<prefix> = .*? '{' (<-[,}]>+) +%% ',' '}' $<postfix> = .* $/;
 
Line 2,111 ⟶ 2,470:
say '';
}
</syntaxhighlight>
</lang>
{{out}}
<pre>simpleNumberRising{1..3}.txt ->
Line 2,202 ⟶ 2,561:
multi char emoji ranges fail {🌵🌵..🌵🌶}
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
Added threea furtherfew more examples to test:the minimum number needed for the task.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
* Mixed number/alpha ranges which apparently are not expanded.
* Stepped alpha ranges which appear to be allowed.
* Stepped ranges which stop after the endpoint (Raku example).
<br>
<lang ecmascript>import "/fmt" for Fmt
 
var parseRange = Fn.new { |r|
Line 2,238 ⟶ 2,592:
asc = !asc
var t = n1
n1var d = (n1 - n2).abs % (-n3)
n1 = n2 - d * (n2 - n1).sign
n2 = t
n3 = -n3
Line 2,289 ⟶ 2,644:
"steppedDownAndPadded-{10..00..5}.txt",
"minusSignFlipsSequence {030..20..-5}.txt",
"reverseSteppedNumberRising{1..6..-2}.txt",
"combined-{Q..P}{2..1}.txt",
"emoji{🌵..🌶}{🌽..🌾}etc",
Line 2,296 ⟶ 2,652:
"mixedNumberAlpha{5..k}",
"steppedAlphaRising{P..Z..2}.txt",
"stops after endpoint-{02..10..3}.txt",
"steppedNumberRising{1..6..2}.txt",
"steppedNumberDescending{20..9..2}",
"steppedAlphaDescending-{Z..M..2}.txt",
"reversedSteppedAlphaDescending-{Z..M..-2}.txt"
]
 
Line 2,304 ⟶ 2,664:
System.print(res.join("\n "))
System.print()
}</langsyntaxhighlight>
 
{{out}}
Line 2,327 ⟶ 2,687:
minusSignFlipsSequence 025.txt
minusSignFlipsSequence 030.txt
 
reverseSteppedNumberRising{1..6..-2}.txt ->
reverseSteppedNumberRising5.txt
reverseSteppedNumberRising3.txt
reverseSteppedNumberRising1.txt
 
combined-{Q..P}{2..1}.txt ->
Line 2,364 ⟶ 2,729:
stops after endpoint-05.txt
stops after endpoint-08.txt
 
steppedNumberRising{1..6..2}.txt ->
steppedNumberRising1.txt
steppedNumberRising3.txt
steppedNumberRising5.txt
 
steppedNumberDescending{20..9..2} ->
steppedNumberDescending20
steppedNumberDescending18
steppedNumberDescending16
steppedNumberDescending14
steppedNumberDescending12
steppedNumberDescending10
 
steppedAlphaDescending-{Z..M..2}.txt ->
steppedAlphaDescending-Z.txt
steppedAlphaDescending-X.txt
steppedAlphaDescending-V.txt
steppedAlphaDescending-T.txt
steppedAlphaDescending-R.txt
steppedAlphaDescending-P.txt
steppedAlphaDescending-N.txt
 
reversedSteppedAlphaDescending-{Z..M..-2}.txt ->
reversedSteppedAlphaDescending-N.txt
reversedSteppedAlphaDescending-P.txt
reversedSteppedAlphaDescending-R.txt
reversedSteppedAlphaDescending-T.txt
reversedSteppedAlphaDescending-V.txt
reversedSteppedAlphaDescending-X.txt
reversedSteppedAlphaDescending-Z.txt
</pre>
2,442

edits