JavaScript中实现sprintf、printf函数


Posted in Javascript onJanuary 27, 2015

在 JavaScript 下实现大多数语言中都有的 sprintf / printf 函数功能。

http://www.webtoolkit.info/javascript-sprintf.html : 比较完整的模拟sprintf函数功能。可用的格式化通配符:
1.%% - 返回百分号本身
2.%b - 二进制数字
3.%c - ASCII对应的字符
4.%d - 整数
5.%f - 浮点数
6.%o - 八进制数字
7.%s - 字符串
8.%x - 16进制数字 (小写字母形式)
9.%X - 16进制数字 (大写字母形式)

在 % 号和通配字符之间可用的选项包括 (比如 %.2f):

1.+      (强制在数字前面显示 + 和 - 符号作为正负数标记。缺省情况下只有负数才显示 - 符号)
2.-      (变量左对齐)
3.0      (使用0作为右对齐的填充字符)
4.[0-9]  (设置变量的最小宽度)
5..[0-9] (设置浮点数精度或字符串的长度)

/**

*

*  Javascript sprintf

*  http://www.webtoolkit.info/

*

*

**/
sprintfWrapper = {
  init : function () {
    if (typeof arguments == "undefined") { return null; }

    if (arguments.length < 1) { return null; }

    if (typeof arguments[0] != "string") { return null; }

    if (typeof RegExp == "undefined") { return null; }
    var string = arguments[0];

    var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);

    var matches = new Array();

    var strings = new Array();

    var convCount = 0;

    var stringPosStart = 0;

    var stringPosEnd = 0;

    var matchPosEnd = 0;

    var newString = '';

    var match = null;
    while (match = exp.exec(string)) {

      if (match[9]) { convCount += 1; }
      stringPosStart = matchPosEnd;

      stringPosEnd = exp.lastIndex - match[0].length;

      strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
      matchPosEnd = exp.lastIndex;

      matches[matches.length] = {

        match: match[0],

        left: match[3] ? true : false,

        sign: match[4] || '',

        pad: match[5] || ' ',

        min: match[6] || 0,

        precision: match[8],

        code: match[9] || '%',

        negative: parseInt(arguments[convCount]) < 0 ? true : false,

        argument: String(arguments[convCount])

      };

    }

    strings[strings.length] = string.substring(matchPosEnd);
    if (matches.length == 0) { return string; }

    if ((arguments.length - 1) < convCount) { return null; }
    var code = null;

    var match = null;

    var i = null;
    for (i=0; i<matches.length; i++) {
      if (matches[i].code == '%') { substitution = '%' }

      else if (matches[i].code == 'b') {

        matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));

        substitution = sprintfWrapper.convert(matches[i], true);

      }

      else if (matches[i].code == 'c') {

        matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));

        substitution = sprintfWrapper.convert(matches[i], true);

      }

      else if (matches[i].code == 'd') {

        matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));

        substitution = sprintfWrapper.convert(matches[i]);

      }

      else if (matches[i].code == 'f') {

        matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));

        substitution = sprintfWrapper.convert(matches[i]);

      }

      else if (matches[i].code == 'o') {

        matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));

        substitution = sprintfWrapper.convert(matches[i]);

      }

      else if (matches[i].code == 's') {

        matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)

        substitution = sprintfWrapper.convert(matches[i], true);

      }

      else if (matches[i].code == 'x') {

        matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));

        substitution = sprintfWrapper.convert(matches[i]);

      }

      else if (matches[i].code == 'X') {

        matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));

        substitution = sprintfWrapper.convert(matches[i]).toUpperCase();

      }

      else {

        substitution = matches[i].match;

      }
      newString += strings[i];

      newString += substitution;
    }

    newString += strings[i];
    return newString;
  },
  convert : function(match, nosign){

    if (nosign) {

      match.sign = '';

    } else {

      match.sign = match.negative ? '-' : match.sign;

    }

    var l = match.min - match.argument.length + 1 - match.sign.length;

    var pad = new Array(l < 0 ? 0 : l).join(match.pad);

    if (!match.left) {

      if (match.pad == "0" || nosign) {

        return match.sign + pad + match.argument;

      } else {

        return pad + match.sign + match.argument;

      }

    } else {

      if (match.pad == "0" || nosign) {

        return match.sign + match.argument + pad.replace(/0/g, ' ');

      } else {

        return match.sign + match.argument + pad;

      }

    }

  }

}
sprintf = sprintfWrapper.init;

如果只是想进行简单的位置变量内容替换而不需要额外的格式化处理的话,可以用比较简单的 YUI tools 中所提供的printf:

YAHOO.Tools.printf = function() {

  var num = arguments.length;

  var oStr = arguments[0];

  for (var i = 1; i < num; i++) {

    var pattern = "\\{" + (i-1) + "\\}";

    var re = new RegExp(pattern, "g");

    oStr = oStr.replace(re, arguments[i]);

  }

  return oStr;

}

使用的时候像 YAHOO.Tools.printf("显示字符串 {0} , {1}。", "1", "2"); 这样用{?}来做匹配。

Javascript 相关文章推荐
Sample script that displays all of the users in a given SQL Server DB
Jun 16 Javascript
IE的fireEvent方法概述及应用
Feb 22 Javascript
Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
Apr 26 Javascript
采用call方式实现js继承
May 20 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
May 28 Javascript
jQuery解决$符号命名冲突
Jun 18 Javascript
JS 获取HTML标签内的子节点的方法
Sep 21 Javascript
详解微信小程序 页面跳转 传递参数
Dec 08 Javascript
LayUI表格批量删除方法
Aug 15 Javascript
vue router 跳转后回到顶部的实例
Aug 31 Javascript
JS实现随机生成10个手机号的方法示例
Dec 07 Javascript
JavaScript中this的全面解析及常见实例
May 14 Javascript
javascript批量修改文件编码格式的方法
Jan 27 #Javascript
JavaScript中的包装对象介绍
Jan 27 #Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
Jan 26 #Javascript
浅谈JavaScript Math和Number对象
Jan 26 #Javascript
js判断一个字符串是否包含一个子串的方法
Jan 26 #Javascript
javascript中Object使用详解
Jan 26 #Javascript
JQuery中的事件及动画用法实例
Jan 26 #Javascript
You might like
常用表单验证类,有了这个,一般的验证就都齐了。
2006/12/06 PHP
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
PHP简单实现循环链表功能示例
2017/11/10 PHP
高亮显示web页表格行的javascript代码
2010/11/19 Javascript
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
得到jQuery detach()后节点中的某个值实现代码
2013/02/05 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
2013/06/08 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
2015/11/06 Javascript
jQuery弹簧插件编写基础之“又见弹窗”
2015/12/11 Javascript
基于vue实现分页/翻页组件paginator示例
2017/03/09 Javascript
javascript 产生随机数的几种方法总结
2017/09/26 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
Vue的elementUI实现自定义主题方法
2018/02/23 Javascript
vue移动端实现下拉刷新
2018/04/22 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
Vuex的API文档说明详解
2020/02/05 Javascript
JsonServer安装及启动过程图解
2020/02/28 Javascript
原生JS实现萤火虫效果
2020/03/07 Javascript
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
跟老齐学Python之传说中的函数编写条规
2014/10/11 Python
探究数组排序提升Python程序的循环的运行效率的原因
2015/04/01 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
2019/11/21 Python
用Python画小女孩放风筝的示例
2019/11/23 Python
在python3.64中安装pyinstaller库的方法步骤
2020/06/02 Python
Python自动化操作实现图例绘制
2020/07/09 Python
印度婴儿用品在线商店:Firstcry.com
2016/12/05 全球购物
IWOOT美国:新奇的小玩意
2018/04/27 全球购物
博柏利美国官方网站:Burberry美国
2020/11/19 全球购物
励志广播稿300字(5篇)
2014/09/15 职场文书
教师查摆问题自查报告
2014/10/11 职场文书
2014年材料员工作总结
2014/11/19 职场文书
同学聚会通知书
2015/04/20 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
初中政治教学反思
2016/02/23 职场文书