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 相关文章推荐
JQuery 文本框使用小结
May 22 Javascript
Jquery中国地图热点效果-鼠标经过弹出提示层信息的简单实例
Feb 12 Javascript
jQuery入门介绍之基础知识
Jan 13 Javascript
使用JS中的exec()方法构造正则表达式验证
Aug 01 Javascript
AngularJs bootstrap搭载前台框架——基础页面
Sep 01 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
Oct 12 Javascript
JS实现图片预加载之无序预加载功能代码
May 12 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
Jul 10 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
详解小程序用户登录状态检查与更新实例
May 15 Javascript
解决layer.open后laydate失效的问题
Sep 06 Javascript
element-ui tooltip修改背景颜色和箭头颜色的实现
Dec 16 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
PHP一些常用的正则表达式字符的一些转换
2008/07/29 PHP
php 设计模式之 工厂模式
2008/12/19 PHP
PHP生成不重复随机数的方法汇总
2014/11/19 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
php实现的mongoDB单例模式操作类
2018/01/20 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
Laravel框架控制器的middleware中间件用法分析
2019/09/30 PHP
Laravel 修改默认日志文件名称和位置的例子
2019/10/17 PHP
javascript 检测浏览器类型和版本的代码
2009/09/15 Javascript
jQuery中parents()和parent()的区别分析
2014/10/28 Javascript
纯jquery实现模仿淘宝购物车结算
2015/08/20 Javascript
AngularJS仿苹果滑屏删除控件
2016/01/18 Javascript
浅谈JQuery+ajax+jsonp 跨域访问
2016/06/25 Javascript
浅谈js原生拖放
2016/11/21 Javascript
angularjs封装$http为factory的方法
2017/05/18 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
vue项目中添加单元测试的方法
2018/07/21 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
JS实现马赛克图片效果完整示例
2019/04/13 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
Python入门之modf()方法的使用
2015/05/15 Python
Python读大数据txt
2016/03/28 Python
python库matplotlib绘制坐标图
2019/10/18 Python
python3 tcp的粘包现象和解决办法解析
2019/12/09 Python
python Qt5实现窗体跟踪鼠标移动
2019/12/13 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
2020/07/13 Python
投资协议书范本
2014/04/21 职场文书
房产协议书范本
2014/10/18 职场文书
兵马俑导游词
2015/02/02 职场文书
2015年科研工作总结范文
2015/05/13 职场文书
什么是执行力?9个故事告诉您:成功绝非偶然!
2019/07/05 职场文书
准备去美国留学,那么大学申请文书应该怎么写?
2019/08/12 职场文书
JavaScript使用canvas绘制坐标和线
2021/04/28 Javascript
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL
Java处理延时任务的常用几种解决方案
2022/06/01 Java/Android