JavaScript或Node.js的string.format,sprintf()等的CoffeeScript版本

8

如何在CoffeeScript中使用string.format()或sprintf()函数?

3个回答

17

这里有两件事情需要注意。第一是插值,Coffeescript 直接支持使用双引号字符串文字和 Ruby 风格的语法来实现,例如:

"The #{speed} #{color} #{animal} jumped over the lazy dog"

这将使用本地作用域中相应变量替换占位符。这是在CoffeeScript(和Ruby)中处理字符串插值的惯用方式。

其次是格式化,如果您想获得具有特定小数位数、以逗号分隔千位数、前导零或类似内容的数字,则可能需要单独处理格式化。但是,CoffeeScript 也可以插入格式化,所以您可以这样做:

"Free shipping on orders over #{currency(freeShipAmount)}"

对于其他使用C风格格式化程序的功能,请查看JavaScript sprintf(我在这个答案中找到)


好的观点 - 感谢您提醒我解释为什么我正在尝试寻找一个string.format()解决方案,而不是使用“....#{var}....”。 - jiy
CoffeeScript 是否有用于前导零的特殊语法? - Hamish Grubijan
不,Coffeescript 具有将任意表达式插入字符串字面量的插值功能。Coffeescript 没有直接支持数据格式化的特殊功能。使用任何 JavaScript 库进行格式化,然后使用 Coffeescript 进行插值即可。 - Peter Lyons

4
这似乎是个有效的方法:
String.prototype.format = ->
  args = arguments
  return this.replace /{(\d+)}/g, (match, number) ->
    return if typeof args[number] isnt 'undefined' then args[number] else match

使用一些fearphage的javascript代码进行翻译。

然后可以像这样使用:

fmt = "<p>{0} {1} (<a href='mailto:{2}'>{2}</a>)</p>"
mystring = fmt.format "Fred", "Flinstone", "fflinstone@bedrock.gov"

那么我的字符串将是:

<p>Fred Flinstone (<a href='mailto:fflinstone@bedrock.gov'>fflinstone@bedrock.gov</a>)</p>

使用#{var}方法(对于给定的示例非常完美)无法处理需要多次重复利用的字符串。例如,在循环情况下:

  HTML_header       = fs.readFileSync('includes/notify/header.html').toString()
  HTML_managerOpen  = fs.readFileSync('includes/notify/managerOpen.html').toString()
  HTML_student      = fs.readFileSync('includes/notify/student.html').toString()
  HTML_managerClose = fs.readFileSync('includes/notify/managerClose.html').toString()
  HTML_footer       = fs.readFileSync('includes/notify/footer.html').toString()

HTML_final = HTML_header

   getter2 = (r, callback) ->
      HTML_final += HTML_managerOpen.format r.EMAIL, r.FNAME, r.LNAME, r.STUDENTS.length, r.PHONE, r.MEMAIL, r.MFNAME, r.MLNAME
      async.forEachSeries r.STUDENTS, getter3, (err) ->
        HTML_final += HTML_managerClose
        callback null

    getter3 = (r, callback) ->
      HTML_final += HTML_student.format r.EMAIL, r.FNAME, r.LNAME, r.PHONE, r.DESCRIPTION, r.ENROLLED, "", "", "", "", "", "", r.CERTEXAMSCORE, r.COIKEY
      callback null

async.forEachSeries results, getter2, (err) ->
  cback null, HTML_final + HTML_footer

2

接受答案的惯用语版本:

String::format = (args...) ->
  @replace /{(\d+)}/g, (match, number) ->
    if number < args.length then args[number] else match

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接