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 相关文章推荐
javascript delete 使用示例代码
Mar 29 Javascript
Js切换功能的简单方法
Nov 23 Javascript
jquery zTree异步加载、模糊搜索简单实例分享
Mar 24 Javascript
onclick和onblur冲突问题的快速解决方法
Apr 28 Javascript
jQuery Easyui 验证两次密码输入是否相等
May 13 Javascript
javascript实现的左右无缝滚动效果
Sep 19 Javascript
Centos7 中 Node.js安装简单方法
Nov 02 Javascript
在vue中使用css modules替代scroped的方法
Mar 10 Javascript
基于vue2.0动态组件及render详解
Mar 17 Javascript
postman+json+springmvc测试批量添加实例
Mar 31 Javascript
Node.js使用cookie保持登录的方法
May 11 Javascript
微信小程序错误this.setData报错及解决过程
Sep 18 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
Win2003下APACHE+PHP5+MYSQL4+PHPMYADMIN 的简易安装配置
2006/11/18 PHP
PHP字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
深入解析php之apc
2013/05/15 PHP
javascript dom 操作详解 js加强
2009/07/13 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
JavaScript简单实现网页回到顶部功能
2013/11/12 Javascript
JS OffsetParent属性深入解析
2014/01/13 Javascript
JavaScript判断用户名和密码不能为空的实现代码
2016/05/16 Javascript
用JavaScript获取页面文档内容的实现代码
2016/06/10 Javascript
微信小程序 向左滑动删除功能的实现
2017/03/10 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
2017/03/25 Javascript
Vue.js数据绑定之data属性
2017/07/07 Javascript
vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法
2018/09/19 Javascript
layui.use模块外部使用其内部定义的js封装函数方法
2019/09/16 Javascript
解决LayUI数据表格复选框不居中显示的问题
2019/09/25 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
2019/11/01 Javascript
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
2021/02/24 Javascript
django 自定义用户user模型的三种方法
2014/11/18 Python
python中sleep函数用法实例分析
2015/04/29 Python
python文件名和文件路径操作实例
2017/09/29 Python
pytorch permute维度转换方法
2018/12/14 Python
python中正则表达式与模式匹配
2019/05/07 Python
python使用 request 发送表单数据操作示例
2019/09/25 Python
复化梯形求积分实例——用Python进行数值计算
2019/11/20 Python
Python定义函数时参数有默认值问题解决
2019/12/19 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
2020/04/14 Python
浅谈python 类方法/静态方法
2020/09/18 Python
Bravofly德国:预订廉价航班和酒店
2019/09/22 全球购物
全球工业:Global Industrial
2020/02/01 全球购物
人事专员职责
2014/02/22 职场文书
2014年三八妇女节活动总结
2014/03/01 职场文书
应届生求职信
2014/05/31 职场文书
团干部培训班心得体会
2016/01/06 职场文书
巾帼建功标兵先进事迹材料
2016/02/29 职场文书
Python 一键获取电脑浏览器的账号密码
2022/05/11 Python