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获取网页中的js、css、Flash等文件
Dec 20 Javascript
js字符编码函数区别分析
Dec 28 Javascript
javascript实现的一个带下拉框功能的文本框
May 08 Javascript
Bootstrap框架动态生成Web页面文章内目录的方法
May 12 Javascript
12 款 JS 代码测试必备工具(翻译)
Dec 13 Javascript
vue自定义filters过滤器
Apr 26 Javascript
React Router V4使用指南(精讲)
Sep 17 Javascript
移动端自适应flexible.js的使用方法(不用三大框架,仅写一个单html页面使用)推荐
Apr 02 Javascript
vue 指令和过滤器的基本使用(品牌管理案例)
Nov 04 Javascript
JS数组的常用10种方法详解
May 08 Javascript
VUE使用axios调用后台API接口的方法
Aug 03 Javascript
vue中watch和computed的区别与使用方法
Aug 23 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
PHPShop存在多个安全漏洞
2006/10/09 PHP
thinkphp3.0 模板中函数的使用
2012/11/13 PHP
php生成随机数的三种方法
2014/09/10 PHP
PHP会话处理的10个函数
2015/08/11 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
PHP下载文件函数与用法示例
2019/09/27 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
jquery中输入验证中一个不错的效果
2010/08/21 Javascript
js中通过父级进行查找定位元素
2014/06/15 Javascript
返回顶部按钮响应滚动且动态显示与隐藏
2014/10/14 Javascript
javaScript实现可缩放的显示区效果代码
2015/10/26 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
2015/11/18 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
React倒计时功能实现代码——解耦通用
2020/09/18 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
[01:03]DOTA2新的征程 你的脚印值得踏上
2014/08/13 DOTA
[45:16]完美世界DOTA2联赛循环赛 IO vs FTD BO2第二场 11.05
2020/11/06 DOTA
[47:43]完美世界DOTA2联赛PWL S3 Magama vs GXR 第二场 12.19
2020/12/24 DOTA
python实现百度关键词排名查询
2014/03/30 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
基于python实现语音录入识别代码实例
2020/01/17 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
python3读取autocad图形文件.py实例
2020/06/05 Python
python3 简单实现组合设计模式
2020/07/02 Python
西班牙在线药店:DosFarma
2020/03/28 全球购物
linux下进程间通信的方式
2014/12/23 面试题
企业管理专业个人求职信范文
2013/09/24 职场文书
国家励志奖学金获奖感言
2014/01/09 职场文书
岗位明星事迹材料
2014/05/18 职场文书
领导干部廉政自律承诺书
2014/05/26 职场文书
社区安全生产月活动总结
2014/07/05 职场文书
三好学生个人总结
2015/02/15 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
一篇文章弄懂Python关键字、标识符和变量
2021/07/15 Python