1/** 2 * $Id: stringextensions.js 147 2006-12-20 22:53:19Z wingedfox $ 3 * $HeadURL: https://svn.debugger.ru/repos/jslibs/BrowserExtensions/tags/BrowserExtensions.003/stringextensions.js $ 4 * 5 * @author Ildar Shaimordanov 6 * @author Ilya Lebedev 7 * @license LGPL 8 * @version $Rev: 147 $ 9 */ 10/** 11 * Method is used to trim specified chars from the left of the string 12 * 13 * @param {String, Array} c char or char list to be trimmed, default is \s 14 * @return {String} 15 * @scope public 16 */ 17String.prototype.ltrim = function(c) { 18 if (isString(c)) c=c.split(""); 19 if (isArray(c) || isUndefined(c)) { 20 c = isEmpty(c)?"\\s":RegExp.escape(c); 21 c = new RegExp("^(?:"+c+")+", "g"); 22 return this.replace(c, ""); 23 } 24 return this; 25} 26/** 27 * Method is used to trim specified list from the right of the string 28 * 29 * @param {String, Array} c char or char sequence to be trimmed, default is \s 30 * @return {String} 31 * @scope public 32 */ 33String.prototype.rtrim = function(c) { 34 if (isString(c)) c=c.split(""); 35 if (isArray(c) || isUndefined(c)) { 36 c = isEmpty(c)?"\\s":RegExp.escape(c); 37 c = new RegExp("(?:"+c+")+$", "g"); 38 return this.replace(c, ""); 39 } 40 return this; 41} 42/** 43 * Method is used to trim specified chars from the left and the right of the string 44 * 45 * @param {String, Array} c char or char list to be trimmed, default is \s 46 * @return {String} 47 * @scope public 48 */ 49String.prototype.trim = function(c) { 50 if (isString(c)) c=c.split(""); 51 if (isArray(c) || isUndefined(c)) { 52 c = isEmpty(c)?"\\s":RegExp.escape(c); 53 c = new RegExp("^(?:"+c+")+|(?:"+c+")+$", "g"); 54 return this.replace(c, ""); 55 } 56 return this; 57} 58 59/** 60 * Duplicates the string 61 * 62 * @return {String} 63 * @scope public 64 */ 65String.prototype.dup = function() { 66 var val = this.valueOf(); 67 return [val,val].join(""); 68} 69/** 70 * Repeats string specified number of times 71 * 72 * @param {Number} n number of times to repeat the string 73 * @return {String} 74 * @scope public 75 */ 76String.prototype.repeat = function(n /* :Number */) /* :String */ { 77 if (isNaN(n=parseInt(n)) || n<0) return ""; 78 return Array(n+1).join(this.valueOf()); 79} 80/** 81 * Pads the string to the specified length 82 * 83 * @param {Number} n number of times to repeat c 84 * positive - on the right side 85 * negative - on the left side 86 * @param {String} c fill char, space is default 87 * @return {String} 88 * @scope public 89 */ 90String.prototype.padding = function(n, c) { 91 var val = this.valueOf(); 92 n = parseInt(n); 93 if (!n) return val; 94 if (isUndefined(c)) c = " "; 95 var pad = String(c).charAt(0).repeat(Math.abs(n) - this.length); 96 return (n < 0) ? pad + val : val + pad; 97} 98/** 99 * Pads the string on the right side 100 * 101 * @param {Number} n number of times to repeat c 102 * @param {String} c fill char 103 * @return {String} 104 * @scope public 105 */ 106String.prototype.padLeft = function(n, c) { 107 return this.padding(-Math.abs(n), c); 108} 109/** 110 * Pads the string on the left side 111 * 112 * @param {Number} n number of times to repeat c 113 * @param {String} c fill char 114 * @return {String} 115 * @scope public 116 */ 117String.prototype.padRight = function(n, c) { 118 return this.padding(Math.abs(n), c); 119} 120 121/** 122 * sprintf(format, argument_list) 123 * 124 * The string format function like the one in C/C++, PHP, Perl 125 * Each conversion specification is defined as below: 126 * 127 * %[index][alignment][padding][width][precision]type 128 * 129 * index An optional index specifier that changes the order of the 130 * arguments in the list to be displayed. 131 * alignment An optional alignment specifier that says if the result should be 132 * left-justified or right-justified. The default is 133 * right-justified; a "-" character here will make it left-justified. 134 * padding An optional padding specifier that says what character will be 135 * used for padding the results to the right string size. This may 136 * be a space character or a "0" (zero character). The default is to 137 * pad with spaces. An alternate padding character can be specified 138 * by prefixing it with a single quote ('). See the examples below. 139 * width An optional number, a width specifier that says how many 140 * characters (minimum) this conversion should result in. 141 * precision An optional precision specifier that says how many decimal digits 142 * should be displayed for floating-point numbers. This option has 143 * no effect for other types than float. 144 * type A type specifier that says what type the argument data should be 145 * treated as. Possible types: 146 * 147 * % - a literal percent character. No argument is required. 148 * b - the argument is treated as an integer, and presented as a binary number. 149 * c - the argument is treated as an integer, and presented as the character 150 * with that ASCII value. 151 * d - the argument is treated as an integer, and presented as a decimal number. 152 * u - the same as "d". 153 * f - the argument is treated as a float, and presented as a floating-point. 154 * o - the argument is treated as an integer, and presented as an octal number. 155 * s - the argument is treated as and presented as a string. 156 * x - the argument is treated as an integer and presented as a hexadecimal 157 * number (with lowercase letters). 158 * X - the argument is treated as an integer and presented as a hexadecimal 159 * number (with uppercase letters). 160 * 161 * @return {String} 162 * @scope public 163 */ 164String.prototype.sprintf = function() { 165 var args = isArray(arguments[0])?arguments[0]:arguments 166 ,index = 0 167 ,frmt = this.replace(/%%/g, "\0\0") 168 ,re = /%((?:\d+\$)?)((?:[-0+# ])?)((?:\d+|\*(?:\d+\$)?)?)((?:.(?:\d+|\*(?:\d+\$)?))?)([bcdeEfosuxX])/g; 169 /* 170 * The re.exec() method returns the array with the following properties 171 * wich are used in this function 172 * x.index contains the substring position found at the origin string 173 * x[0] contains the found substring 174 * x[1] contains the explicit parameter number 175 * x[2] contains the flags 176 * x[3] contains the minwidth 177 * x[4] contains the precision 178 * x[5] contains the type specifier (as [bcdfosuxX]) 179 */ 180 frmt = frmt.replace(re, function() { 181 var x = arguments 182 ,sign = false 183 ,ins; 184 185 /* 186 * calculate min width 187 */ 188 if (!isUndefined(x[3]) && x[3].indexOf("*")==0) { 189 x[3] = parseInt(x[3].replace(/\D/g,"")) 190 if (isNaN(x[3])) { 191 x[3] = args[index]; 192 /* 193 * increment 194 */ 195 index++; 196 } else { 197 x[3] = args[x[3]] 198 } 199 } 200 /* 201 * calculate precision 202 */ 203 if ("" != x[4]) { 204 if (x[4].indexOf("*")==1) { 205 x[4] = parseInt(x[4].replace(/\D/g,"")) 206 if (isNaN(x[4])) { 207 x[4] = args[index]; 208 /* 209 * increment 210 */ 211 index++; 212 } else { 213 x[4] = args[x[4]] 214 } 215 } else { 216 x[4] = x[4].replace(/\D/,"") 217 } 218 x[4] = Math.abs(x[4]); 219 } 220 /* 221 * calculate insertion value 222 */ 223 x[1] = parseInt(x[1]); 224 var ins; 225 if (isNumeric(x[1])) { 226 ins = args[x[1]]; 227 } else { 228 ins = args[index]; 229 /* 230 * index should be incremented only when no explicit parameter number is specified 231 */ 232 index++; 233 } 234 switch (x[5]) { 235 case "b": 236 if (ins<0) ins = 0x10000000000000000+parseInt(ins); 237 ins = Number(ins).bin(x[4]); 238 if (x[4]) ins = ins.substr(0,x[4]); 239 if (x[2]=='#') ins = '0b'+ins; 240 break; 241 case "c": 242 ins = String.fromCharCode(ins); 243 break; 244 case "u": 245 ins = Math.abs(ins); 246 case "d": 247 ins = Math.round(ins); 248 if (ins<0) { 249 ins = "-"+Math.abs(ins).dec(x[4]); 250 } else { 251 ins = Number(ins).dec(x[4]); 252 sign = (x[2] == ' ' || x[2] == '+'); 253 } 254 break; 255 case "e": 256 case "E": 257 if (ins>0) { 258 sign = (x[2] == ' ' || x[2] == '+'); 259 } 260 ins = Number(ins).toExponential(x[4]?x[4]:6); 261 if (x[5]=='E') ins=ins.toUpperCase(); 262 break; 263 case "f": 264 if (ins>0) { 265 sign = (x[2] == ' ' || x[2] == '+'); 266 } 267 ins = Number(ins).toFixed(isNumeric(x[4])?x[4]:6); 268 break; 269 case "o": 270 if (ins<0) ins = 0x10000000000000000+parseInt(ins); 271 ins = Number(ins).toString(8); 272 if (x[4]) ins = ins.substr(0,x[4]); 273 if (x[2]=='#' && ins != 0) ins = '0'+ins; 274 break; 275 case "s": 276 ins = String(ins); 277 if (x[4]) ins = ins.substr(0,x[4]); 278 break; 279 case "x": 280 case "X": 281 if (ins<0) ins = 0x10000000000000000+parseInt(ins); 282 ins = Number(ins).hex(-x[4]); 283 if (x[4]) ins = ins.substr(0,x[4]); 284 if (x[2]=='#') ins = '0x'+ins; 285 if (x[5]=='X') ins = ins.toUpperCase(); 286 break; 287 } 288 if (sign) ins = x[2]+ins; 289 if (x[3]) ins = (x[2]=='-' || x[3]<0)?ins.padRight(x[3]):ins.padLeft(x[3],x[2]=='0'?0:" "); 290 return ins; 291 }) 292 return frmt.replace(/\0\0/g, "%"); 293} 294