Florian Baierl
Florian Baierl

Reputation: 2481

String interpolation like java.text.MessageFormat for scala.js

I need a string interpolation like java.text.MessageFormat for scala.js. Specifically I need something that lets me chose the order in which my parameters are printed (like '{0}', '{1}') for our translations.

What I want:

val world = "world"
format("Hello {0}", world)
format("Hello {1}{0}", "!", world) // should print: "Hello world!"

What I cannot use:

"Hello $world"  
"Hello %s".format(world)

Anything I can use and just haven't found yet? For consitency I would definetly prefer to use '{x}'s in my Strings.

EDIT:

Using sjrd's answer, I came up with the following:

/**
* String interpolation [[java.text.MessageFormat]] style:
* {{{
*   format("{1} {0}", "world", "hello") // result: "hello world"
*   format("{0} + {1} = {2}", 1, 2, "three") // result: "1 + 2 = three"
*   format("{0} + {0} = {0}", 0) // throws MissingFormatArgumentException
* }}}
* @return
*/
def format (text: String, args: Any*): String = {
   var scalaStyled = text
   val pattern = """{\d+}""".r
   pattern.findAllIn(text).matchData foreach {
      m => val singleMatch = m.group(0)
           var number = singleMatch.substring(1, singleMatch.length - 1).toInt
           // %0$s is not allowed so we add +1 to all numbers
           number = 1 + number
           scalaStyled = scalaStyled.replace(singleMatch, "%" + number + "$s")
   }
   scalaStyled.format(args:_*)
}

Upvotes: 1

Views: 673

Answers (1)

sjrd
sjrd

Reputation: 22085

You can use String.format with explicit indices:

val world = "world"
"Hello %1$s".format(world)
"Hello %2$s%1$s".format("!", "world")

Explicit indices are specified before a $. They are 1-based.

It's not as pretty as {x}, but you if you really want that, you could define a custom function that translates the {x} into %x$s before giving them to format.

Upvotes: 4

Related Questions