最近做了不少H5项目,功能比较简单,为减少体积且便于利用无线团队的其他模块前端库基于zepto。这个项目中有因为页面是由前端渲染了的,所以自然有很多拼字符串的操作。在zepto中找了半天也没有找到一个类似kissy中subsititute函数的功能,于是自己写了一个。用起来还算顺手,所以放上来大家交流下。为了避免与HTML属性的JSON格式冲突,通配符借鉴了ruby的方案,使用了#{}。对zepto还不是很熟悉,有更好的方案欢迎大家留言指出。
/**
* @fileOverview 简单字符串工具类.
* @since 2014.06.19
*/
;(function($, util){
var REG_PROP_NAME = (
'(?:' //属性名称可以是字母或由引号引起的字符串
+ '\\w+'
+ "|'(?:[^\\']|\\\\.)+'"
+ '|"(?:[^\\"]|\\\\.)+"'
+ ')'
);
var readProp = function(obj, propStr){
var i, c, prop, val, len;
var reg = new RegExp(REG_PROP_NAME, 'g');
var props = propStr.match(reg).map(function(i){
return i.trim().replace(/^['"]|['"]$/g, '');
});
len = props.length;
if( len == 1 ){
val = obj[props[0]];
return (typeof val != undefined) ? val : '';
}
for(i=0, c=len-1; i < c; i++){
prop = props[i];
if(typeof obj[prop] == undefined){
return '';
}
obj = obj[prop];
}
val = obj[props[len-1]];
return (typeof val != undefined) ? val : '';
};
var StrUtil = {
/**
* 将模板中的变量替换为值后返回.
* @param {String}tmpl
* @parma {JSON}props
* @return {String}
* @public
* @example
* var tmpl = 'hello #{name}, #{age}, \#{name}';
* var props = {name: 'zhang-san', age: 20};
* console.log(util.str.sub(tmpl, props); // => hello zhang-san, 20, #{name}
*
* var tmpl2 = (
* 'name: #{user.name} \n'
* + 'age : #{user.age } \n'
* + 'address: \n'
* + ' home-town: #{user.address."home-town"} \n'
* + ' current-city: #{user.address.city} \n'
* );
*
* var props = {
* user: {
* name: 'zhang-san',
* age: 20,
* address: {
* "home-town" : "hebei",
* city: 'bei-jing'
* }
* }
* };
*
* console.log(util.str.sub(tmpl2, props));
*/
sub : function(tmpl, obj){
var reg = new RegExp((
'\\\\(.)' //转义字符
+ '|#\\{\\s*(' //或者#{prop1.prop2."prop-3"}
+ REG_PROP_NAME
+ '(?:'
+ '\\.'
+ REG_PROP_NAME
+ ')*'
+ ')\\s*\\}'
), 'gi');
var func = function(m, $1, $2){
return ($1 != undefined) ? $1 : readProp(obj, $2);
};
return tmpl.replace(reg, func);
}
};
util.str = StrUtil;
})(window.$, window.util || (window.util = {}));