Reducing Verbosity in formatted strings (Stanza)

35 views Asked by At

I'm crafting many strings from a few base strings for regex-related operations, and I am wondering if there is a less verbose way to write this.

I have for my base strings:

val ALPHA = "[a-zA-Z]"
val ODD = "[13579]"
val EVEN = "[02468]"
val INEQ = "[<>]"

Strings built from these:

val S1 = to-string $ "Today's math lesson is (%_) %_ (%_|%_)" % [ODD INEQ ODD EVEN]
val S2 = to-string $ "My boat is named (%_+)" % [ALPHA]
val S3 = to-string $ "Hashed password is ((?:%_|%_|%_)+)" % [ALPHA ODD EVEN]
... (many more)

Ideally I could write something along the lines of

evaluate-template $ "Today's math lesson is ({ODD}) {INEQ} ({ODD}|{EVEN})"
1

There are 1 answers

0
Mike Hilgendorf On

I think for a problem like composing regular expressions you might want something more robust than format strings. For example, declaring a Regex type:

deftype Regex:
  String <: Regex

defstruct AnyOf <: Regex:
  regexes:Tuple<Regex>

defmethod print (o:OutputStream, a:AnyOf):
  val rs = regexes(a)
  val last = length(rs) - 1
  print(o, "(%*|%_)" % [rs[0 to last], rs[last]])
  
defstruct AllOf <: Regex:
  regexes:Tuple<Regex>

defmethod print (o:OutputStream, a:AllOf):
  print(o, "%*" % [regexes(a)])

defstruct AtLeastOne  <: Regex:
  regex:Regex

defmethod print (o:OutputStream, a:AtLeastOne):
  print(o, "%_+" % [regex(a)])

defstruct ZeroOrMore <: Regex:
  regex:Regex

defmethod print (o:OutputStream, a:ZeroOrMore):
  print(o, "%_*" % [regex(a)])

val ALPHA: Regex = "[a-zA-Z]"
val ODD  : Regex = "[13579]"
val EVEN : Regex = "[02468]"
val INEQ : Regex = "[<>]"

println(AllOf(["Today's math lesson is ", ODD, " ", INEQ, " ", AnyOf([ODD, EVEN])]))

this program prints:

Today's math lesson is [13579] [<>] ([13579]|[02468])

Sidenote: GNU grep doesn't like this result, so it might need tuning.