我有以下javascript函数,它使用了很多正则表达式。有没有办法可以简化这个?
function encode(str){
if(typeof str==='number'){
return str;
}
if(typeof str!=='string'){
return '';
}
var enc=str;
enc=enc.replace(/_/g,'_u'); //underscore
enc=enc.replace(/(\r\n|\r|\n)/g,'_r'); //return
enc=enc.replace(/&/g,'_a'); //ampersand
enc=enc.replace(/\\/g,'_b'); //backslash
enc=enc.replace(/:/g,'_c'); //colon
enc=enc.replace(/"/g,'_d'); //double quote
enc=enc.replace(/=/g,'_e'); //equals
enc=enc.replace(/€/g,'_4'); //euro
enc=enc.replace(/\>/g,'_g'); //greater than
enc=enc.replace(/#/g,'_h'); //hash
enc=enc.replace(/'/g,'_i'); //inverted comma
enc=enc.replace(/\</g,'_l'); //less than
enc=enc.replace(/¬/g,'_n'); //not
enc=enc.replace(/\|/g,'_1'); //pipe
enc=enc.replace(/¦/g,'_2'); //broken pipe
enc=enc.replace(/\+/g,'_p'); //plus
enc=enc.replace(/£/g,'_3'); //pound
enc=enc.replace(/\?/g,'_q'); //question mark
enc=enc.replace(/\//g,'_s'); //slash
enc=enc.replace(/\~/g,'_t'); //tlide
enc=enc.replace(/\`/g,'_z'); //back quote
enc=enc.replace(/\s/g,'_0'); //space
enc=enc.replace(/[\u0000-\u001f]/g,'');
return enc;
};
答案 0 :(得分:3)
您可以改为创建一个从“string to replace”到“replacement”的地图,然后使用带有回调的单个替换函数,而不是创建“pattern”到“replacement”的映射:
var map = {
"_": "_u",
"\r\n": "_r",
"\r": "_r",
"\n": "_r",
"&": "_a",
/* .. etc .. */
};
enc = enc.replace(
/\r\n|[_\r\n&\\:"=€>#'<¬|¦+£?\/~`\s\u0000-\u001f]/g,
function(m) {
return map[m[0]];
}
);
只要添加不会导致固定字符串的替换模式,这种方法就会失败(因为它们使用的是+
或*
等量词。
然而,在大多数浏览器中它实际上要快得多。请参阅this JSPerf。
除此之外,没有办法进行条件替换(这是进一步优化所需的)。
答案 1 :(得分:1)
您可以这样做:
var map = {
"_": "_u",
"(\r\n|\r|\n)": "_r",
"&": "_a",
/* .. etc .. */
};
var i;
var enc = "_abc&";
for (i in map) {
enc = enc.replace(new RegExp(i, "g"), map[i]);
}
console.log(enc); // _uabc_a
我使用new RegExp
,因为你无法撰写正则表达式。请注意,您不需要分隔符(/
),修饰符(g
)也在其他位置。