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 相关文章推荐
用JS写的一个TableView控件代码
Jan 23 Javascript
jQuery实现360°全景拖动展示
Mar 18 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
jquery ajax双击div可直接修改div中的内容
Mar 04 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
Angular.js中用ng-repeat-start实现自定义显示
Oct 18 Javascript
利用JQuery阻止事件冒泡
Dec 01 Javascript
Angular4开发解决跨域问题详解
Aug 28 Javascript
react-native-fs实现文件下载、文本存储的示例代码
Sep 22 Javascript
详解VUE项目中安装和使用vant组件
Apr 28 Javascript
解决Antd 里面的select 选择框联动触发的问题
Oct 24 Javascript
前端vue如何使用高德地图
Nov 05 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代码质量36计
2012/09/05 PHP
PHP使用PHPexcel导入导出数据的方法
2015/11/14 PHP
PHP设计模式之简单投诉页面实例
2016/02/24 PHP
PHP如何实现阿里云短信sdk灵活应用在项目中的方法
2019/06/14 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
JS中Iframe之间传值及子页面与父页面应用
2013/03/11 Javascript
js onload事件不起作用示例分析
2013/10/09 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
JavaScript动态添加列的方法
2015/03/25 Javascript
一个极为简单的requirejs实现方法
2016/10/20 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
2018/06/19 Javascript
layui select获取自定义属性方法
2018/08/15 Javascript
vue把输入框的内容添加到页面的实例讲解
2019/11/11 Javascript
NestJs使用Mongoose对MongoDB操作的方法
2021/02/22 Javascript
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
python3实现暴力穷举博客园密码
2016/06/19 Python
Python 模块EasyGui详细介绍
2017/02/19 Python
人机交互程序 python实现人机对话
2017/11/14 Python
python实现ftp文件传输功能
2020/03/20 Python
Python Scrapy多页数据爬取实现过程解析
2020/06/12 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
2020/06/17 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
keras实现VGG16方式(预测一张图片)
2020/07/07 Python
Django如何实现密码错误报错提醒
2020/09/04 Python
Moss Bros官网:英国排名第一的西装店
2020/02/26 全球购物
英语专业大学生求职简历的自我评价
2013/10/18 职场文书
八一演出活动方案
2014/02/03 职场文书
调解员先进事迹材料
2014/02/07 职场文书
高级销售求职信
2014/02/21 职场文书
农村产权制度改革实施方案
2014/03/21 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
教导主任个人总结
2015/03/03 职场文书
童年读书笔记
2015/06/26 职场文书
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python
vue实现在data里引入相对路径
2022/06/05 Vue.js
Python中的 No Module named ***问题及解决
2022/07/23 Python