      1 ﻿
      2 /**
      3  * @name	CeL function for native objects
      4  * @fileoverview
      5  * 本檔案包含了 native objects 的 functions。
      6  * @since
      7  */
      8
      9
     10 if (typeof CeL === 'function')
     11 CeL.setup_module('data.native',
     12 {
     13 require : 'data.split_String_to_Object',
     14 code : function(library_namespace, load_arguments) {
     15
     16 //	requiring
     17 var split_String_to_Object;
     18 eval(library_namespace.use_function(this));
     19
     20
     21 /**
     22  * null module constructor
     23  * @class	native objects 的 functions
     24  */
     25 CeL.data.native
     26 = function() {
     27 	//	null module constructor
     28 };
     29
     30
     31 /**
     32  * for JSDT: 有 prototype 才會將之當作 Class
     33  */
     34 CeL.data.native
     35 .prototype = {
     36 };
     37
     38
     39
     40
     41
     42
     43 /*	opposite of toUTCString()
     44 	尚不成熟！假如是type=='date'，不如用new Date()!
     45 	string大部分可用new Date(Date.parse(str))代替!
     46 	http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K742.aspx
     47
     48 var UTCDay,UTCMonth;
     49 setObjValue('UTCDay','Sun,Mon,Tue,Wed,Thu,Fri,Sat',1);
     50 setObjValue('UTCMonth','Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',1);
     51 var fromUTCStringFormat=[[0,3,2,1,4],[0,5,1,2,3],[0,4,1,2,3]];	//	0:[Mon, 9 Aug 2004 12:05:00 GMT],1:[Thu Sep 30 18:12:08 UTC+0800 2004],2:[Sat Jun 26 18:19:46 2004]
     52 function fromUTCString(str,format){
     53  var s=''+str,f;
     54  if(!s)return;
     55  if(typeof format=='undefined')if(f=Date.parse(s))return new Date(f);else return 'Unknown format!';//format=0;
     56  if(!isNaN(format)&&format<fromUTCStringFormat.length)f=fromUTCStringFormat[format];
     57  else return 'Yet support this kind of format['+format+']!\nWe support to '+fromUTCStringFormat.length+'.';
     58  if(!f[0])f[0]=' ';
     59  s=s.replace(new RegExp(f[0]+'+','g'),f[0]).split(f[0]);
     60  if(s.length<f.length)return 'The item length of data: '+s.length+' is less then format['+format+']: '+f.length+'!\n'+s.join(',');// new Date
     61  if(f.length==5)s[f[4]]=s[f[4]].split(':');
     62  else if(f.length==7)s[f[4]]=[s[f[4]],s[f[5]],s[f[6]]];
     63  else return 'Illegal date format!';
     64  if(format==1&&s[4].match(/([+-]\d{2})/))s[f[4]][0]=parseInt(s[f[3]][0])+parseInt(RegExp.$1);
     65  alert(str+'\n'+s[f[1]]+','+s[f[2]]+'('+UTCMonth[s[f[2]]]+'),'+s[f[3]]+','+s[f[4]][0]+','+s[f[4]][1]+','+s[f[4]][2]);
     66  //	check,可以包括星期
     67  if( !(s[f[2]]=UTCMonth[s[f[2]]]) || !(s=new Date(s[f[1]],s[f[2]],s[f[3]],s[f[4]][0],s[f[4]][1],s[f[4]][2])) )	//	Date.UTC()
     68   s='Input data error!';
     69  return s;
     70 }
     71 */
     72
     73 /*	string <-> date object, Date.parse()
     74 	http://msdn2.microsoft.com/zh-tw/library/t5580e8h(VS.80).aspx
     75
     76
     77 /((\d{1,4})[\/.-])?([01]?\d)([\/.-]([0-3]?\d))?/
     78 /([0-2]?\d):([0-5]?\d)(:([0-5]?\d))?\s*(([PA])M)?/
     79
     80
     81 (
     82
     83
     84 (
     85
     86
     87 (
     88 ([12]\d{3}|1?\d{2})
     89
     90 [\/.-]
     91 )?
     92
     93 ([01]?\d)
     94
     95 ([\/.-]([0-3]?\d)(\.\d+)?)?
     96
     97
     98 |
     99
    100
    101 ([0-2]?\d)
    102 :
    103 ([0-5]?\d)
    104
    105 (:([0-5]?\d))?
    106
    107 \s*
    108 (([PA])M)?
    109
    110
    111 )
    112
    113
    114
    115 \s*
    116 ){1,2}
    117
    118
    119 try:
    120 '2003/1/4  12:53:5'.toDate();
    121 String_to_Date.m.join('<br/>');
    122 	$2:year
    123 	$3:month
    124 	$5:mday
    125
    126
    127 */
    128 String_to_Date.pd=/(([12]\d{3}|1\d{2}|[2-9]\d)[\/.\-–年])?([01]?\d)([\/.\-–月]([0-3]?\d)日?)?/;	//	pattern of date
    129 String_to_Date.pt=/([0-2]?\d)[:時]([0-5]?\d)([:分]([0-5]?\d)(\.\d+)?)?\s*(([PA])M)?/i;	//	pattern of time
    130 String_to_Date.r1=new RegExp(String_to_Date.pd.source+'(\\s+'+String_to_Date.pt.source+')?','i');	//	date [time]
    131 String_to_Date.r2=new RegExp(String_to_Date.pt.source+'(\\s+'+String_to_Date.pd.source+')?','i');	//	time [date]
    132 //String_to_Date.m;	//	matched string
    133 function String_to_Date(s,f,diff){	//	date string, force parse(no Date.parse() try), 時差 in hour(例如 TW: UTC+8 → 8, 可使用.5)
    134  if(!s)s=this.valueOf();//.toString();
    135  var m,a,b,c;
    136  if(!f&&!diff&&(m=Date.parse(s)))return new Date(m);	//	有diff時不使用 Date.parse
    137
    138  if(m=s.match(/(^|[^\d])([12]\d{3})([^\/.\-–年]|$)/))s=m[2]+'/1';	//	僅有年時的bug
    139
    140  f=1911;	//	小於此年份會加上此年份。for 民國
    141  if(diff)diff=(new Date).getTimezoneOffset()+parseInt(60*diff);
    142  if(!diff)diff=0;
    143  if(m=s.match(String_to_Date.r1))
    144   //	日期先
    145   //for(var i=1;i<11;i++)m[i]=m[i]?Math.floor(m[i]):0;	//	needless
    146   a=new Date((b=m[2]-0)&&b<200?b+f:b,m[3]?m[3]-1:0,m[5]||1,	m[12]=='P'||m[13]=='p'?m[7]-0+12:m[7],m[8]-diff,m[10],m[11]*1e3);
    147
    148  if((!m||!isNaN(m[0]))&&(c=s.match(String_to_Date.r2)))	//	不match或僅有一數字
    149   //	時間先
    150   m=c,a=new Date((b=m[10]-0)&&b<200?b+f:b,m[11]?m[11]-1:0,m[13]||1,	m[7]=='P'||m[7]=='p'?m[1]-0+12:m[1],m[2]-diff,m[4],m[5]*1e3);
    151
    152  //var t="match:\n"+s+"\n\n";for(var i=0;i<m.length;i++){t+=(i>9?i:' '+i)+': '+m[i]+'\n';}if(!m[1]||!m[2]||!m[4])alert(t);
    153
    154  if (String_to_Date.m = m) {
    155   //	判別未輸入時預設年份設對了沒：以最接近 now 的為基準
    156   if (!b && a - new Date(0, 0, 2) > 0) {
    157 					m = new Date(a);
    158 					a.setFullYear(s = (b = new Date).getFullYear());
    159 					m.setFullYear(a - b > 0 ? s - 1 : s + 1);
    160 					if (a - b > 0 && a - b > b - m || a - b < 0
    161 							&& a - b < b - m)
    162 						a = m;
    163 				}
    164   return a;
    165  }
    166 }
    167
    168 //	Turn to RFC 822 date-time
    169 //DateToRFC822[generateCode.dLK]='setTool,String_to_Date';
    170 function DateToRFC822(d) {
    171 	if (!(d instanceof Date))
    172 		d = ('' + d).toDate();
    173 	if (!d)
    174 		d = new Date;
    175 	return d.toGMTString().replace(/UTC/gi, 'GMT');
    176 };
    177
    178 //	要用更多樣化的，請使用format_date()
    179 function Date_to_String(sp) {
    180 	if (!sp)
    181 		sp = '/';
    182 	with (this)
    183 		return '' + getYear() + sp + (getMonth() + 1) + sp + getDate() + ' '
    184 				+ getHours() + ':' + getMinutes()
    185 		// +':'+.getSeconds()+'.'+getMilliseconds();
    186 		;
    187 };
    188 //var tt='2001/8/7 03:35PM';alert(tt+'\n'+tt.toDate().toStr());
    189
    190
    191 /*
    192 mode:
    193 	+4:不顯示時間,
    194 	+3:顯示時間至時,
    195 	+2:顯示時間至分,
    196 	+1:顯示時間至秒,
    197 	+0:顯示時間至毫秒(ms)
    198
    199 	+32(4<<3):不顯示日期,
    200 	+24(3<<3):顯示日期mm/dd,
    201 	+16(2<<3):顯示日期yyyy/mm,
    202 	+8(1<<3):顯示日期yyyy/mm/dd(星期),
    203 	+0:顯示日期yyyy/mm/dd
    204
    205 	+64(1<<6):input UTC
    206 	+128(2<<6):output UTC
    207
    208 NOTE:
    209 在現有時制下要轉換其他時區之時間成正確time:
    210 d=_其他時區之時間_;
    211 diff=其他時區之時差(例如 TW: UTC+8)
    212 d.setTime(d.getTime()-60000*((new Date).getTimezoneOffset()+diff*60))
    213
    214 */
    215
    216 CeL.data.native
    217 .
    218 /**
    219  * 顯示格式化日期 string
    220  * @param date_value	要轉換的 date, 值過小時當作時間, <0 轉成當下時間
    221  * @param {Number} mode	要轉換的 mode
    222  * @param {Boolean} zero_fill	對 0-9 是否補零
    223  * @param {String} date_separator	date separator
    224  * @param {String} time_separator	time separator
    225  * @return	{String}	格式化後的日期
    226  * @example
    227  * alert(format_date());
    228  * @since	2003/10/18 1:04 修正
    229  * @since	2010/4/16 10:37:30	重構(refactoring)
    230  * @requires setTool,to_fixed
    231  * @see
    232  * http://www.merlyn.demon.co.uk/js-dates.htm,
    233  * http://aa.usno.navy.mil/data/docs/JulianDate.html
    234  * @memberOf	CeL.data.native
    235  */
    236 format_date = function format_date(date_value, mode, zero_fill, date_separator, time_separator) {
    237 	//library_namespace.debug('[' + (typeof date_value) + '] ' + date_value + ', mode: ' + mode);
    238
    239 	// initiate
    240 	if (!mode)
    241 		mode = 0;
    242
    243 	var output_UTC, a, b = mode, time_mode, return_string = '',
    244 	show_number = zero_fill ? function(n) {
    245 		return n > 9 ? n : '0' + n;
    246 	} : function(n) {
    247 		return n;
    248 	};
    249
    250 	//	date & time mode
    251 	mode %= 64;
    252 	//	UTC mode
    253 	b = (b - mode) / 64;
    254 	//	input UTC
    255 	a = b % 2 == 1 ? 1 : 0;
    256 	output_UTC = b - a === 1;
    257
    258 	time_mode = mode % 8;
    259 	//	date mode
    260 	mode = (mode - time_mode) / 8;
    261 	// time_mode > 4 && mode > 3: error mode: 沒啥好顯示的了
    262
    263 	//	處理各種不同的 date
    264 	b = typeof date_value;
    265 	if (b === 'number' && date_value >= 0){
    266 		// 全球標準時間(UCT)與本地時間之差距
    267 		// UTC time = local time + format_date.UTC_offset(ms)
    268 		if (!a && isNaN(a = format_date.UTC_offset))
    269 			//	input UTC 時之差距(ms)
    270 			//	.getTimezoneOffset() is in minute. 60*1000(ms)=6e4(ms)
    271 			a = format_date.UTC_offset = 6e4 * (new Date).getTimezoneOffset();
    272
    273 		// 值過小時當作時間: d<90000000~24*60*60*1000，判別為當天，只顯示時間。不允許 d<0！
    274 		date_value = new Date(Math.abs(a += date_value) < 9e7 ? a : date_value);
    275 		mode = 32;
    276 	}else if (b === 'string' && (a = date_value.toDate()))
    277 		date_value = a;
    278 	else if (b === 'date')
    279 		// 應對在 Excel 等外部程式會出現的東西
    280 		date_value = new Date(date_value);
    281 	else if (
    282 			//	http://www.interq.or.jp/student/exeal/dss/ejs/1/1.html
    283 			//	引数がオブジェクトを要求してくる場合は instanceof 演算子を使用します
    284 			//	typeof date_value!=='object'||date_value.constructor!=Date
    285 			!(date_value instanceof Date))
    286 		//	new Date === new Date()
    287 		date_value = new Date;
    288
    289
    290 	// 處理 date
    291 	if (mode < 4) {
    292 		return_string = show_number((output_UTC ? date_value.getUTCMonth()
    293 				: date_value.getMonth()) + 1);
    294 		if (!date_separator)
    295 			date_separator = '/';
    296 		if (mode < 3)
    297 			return_string = (output_UTC ? date_value.getUTCFullYear() : date_value
    298 					.getFullYear())
    299 					+ date_separator + return_string;
    300 		if (mode !== 2) {
    301 			return_string += date_separator
    302 			+ show_number(output_UTC ? date_value.getUTCDate() : date_value
    303 					.getDate());
    304 			if (mode === 1)
    305 				return_string += '(' + (output_UTC ? date_value.getUTCDay()
    306 						: date_value.getDay()) + ')';
    307 		}
    308 	}
    309
    310 	// 處理 time
    311 	if (time_mode < 4) {
    312 		if (mode < 4)
    313 			// 日期 & 時間中間分隔
    314 			return_string += ' ';
    315 		if (!time_separator)
    316 			time_separator = ':';
    317 		return_string += show_number(output_UTC ? date_value.getUTCHours()
    318 				: date_value.getHours());
    319 		if (time_mode < 3) {
    320 			return_string += time_separator
    321 			+ show_number(output_UTC ? date_value.getUTCMinutes()
    322 					: date_value.getMinutes());
    323 			if (time_mode < 2)
    324 				return_string += time_separator
    325 				+ (time_mode ? show_number(output_UTC ? date_value
    326 						.getUTCSeconds() : date_value.getSeconds())
    327 						: (output_UTC ? date_value.getUTCSeconds()
    328 								+ date_value.getUTCMilliseconds() / 1e3
    329 								: date_value.getSeconds() + date_value.getMilliseconds() / 1e3
    330 							).to_fixed(3));
    331 		}
    332 	}
    333
    334 	return return_string;
    335 };
    336
    337
    338
    339 /*
    340 	function經ScriptEngine會轉成/取用'function'開始到'}'為止的字串
    341
    342 	用[var thisFuncName=parse_function().funcName]可得本身之函數名
    343 	if(_detect_)alert('double run '+parse_function().funcName+'() by '+parse_function(arguments.callee.caller).funcName+'()!');
    344
    345 You may use this.constructor
    346
    347
    348 TODO:
    349 to call: parse_function(this,arguments)
    350 e.g., parent_func.child_func=function(){var name=parse_function(this,arguments);}
    351
    352 bug:
    353 函數定義 .toString() 時無法使用。
    354 */
    355 CeL.data.native
    356 .
    357 /**
    358  * 函數的文字解譯/取得函數的語法
    359  * @param {Function|String} function_name	function name or function structure
    360  * @param flag	=1: reduce
    361  * @return
    362  * @example
    363  * parsed_data = new parse_function(function_name);
    364  * @see
    365  * http://www.interq.or.jp/student/exeal/dss/ref/jscript/object/function.html,
    366  * Syntax error: http://msdn.microsoft.com/library/en-us/script56/html/js56jserrsyntaxerror.asp
    367  * @memberOf	CeL.data.native
    368  * @since	2010/5/16 23:04:54
    369  */
    370 parse_function = function parse_function(function_name, flag) {
    371 	if (!function_name
    372 			&& typeof (function_name = parse_function.caller) !== 'function')
    373 		return;
    374 	if (typeof function_name === 'string'
    375 			&& !(function_name = library_namespace.get_various(function_name)))
    376 		return;
    377
    378 	var fs = '' + function_name, m = fs.match(/^function[\s\n]+(\w*)[\s\n]*\(([\w,\s\n]*)\)[\s\n]*\{[\s\n]*((.|\n)*)[\s\n]*\}[\s\n]*$/);
    379 	//library_namespace.debug(typeof function_name + '\n' + fs + '\n' + m);
    380
    381 	// detect error, 包含引數
    382 	// 原先：functionRegExp=/^\s*function\s+(\w+) ..
    383 	// 因為有function(~){~}這種的，所以改變。
    384 	if (!m)
    385 		// JScript5 不能用throw!
    386 		// http://www.oldversion.com/Internet-Explorer.html
    387 		throw new Error(1002, 'Syntax error (語法錯誤)');
    388
    389 	if (function_name != m[1])
    390 		library_namespace.warn('Function name unmatch (函數名稱不相符，可能是用了reference？)');
    391
    392 	//library_namespace.debug('function ' + m[1] + '(' + m[2] + '){\n' + m[3] + '\n}');
    393
    394 	return {
    395 		string : fs,
    396 		name : m[1],
    397 		// 去除前後空白
    398 		arguments : m[2].replace(/[\s\n]+/g, '').split(','),
    399 		code : m[3]
    400 	};
    401 };
    402
    403
    404
    405
    406 //	補強String.fromCharCode()
    407 function fromCharCode(c) {
    408 	if (!isNaN(c))
    409 		return String.fromCharCode(c);
    410 	try {
    411 		// 直接最快
    412 		return eval('String.fromCharCode(' + c + ');');
    413 	} catch (e) {
    414 	}
    415
    416 /*
    417 if (typeof c == 'string')
    418 	return eval('String.fromCharCode(' + n + ')');// c=c.split(','); 後者可以通過審查
    419 if (typeof c == 'object') {
    420 	var t = '', d, i, a, n = [];
    421 	if (c.length)
    422 		a = c;
    423 	else {
    424 		a = [];
    425 		for (i in c)
    426 			a.push(c[i]);
    427 	}
    428 	for (i = 0; i < a.length; i++)
    429 		if (!isNaN(c = a[i]) || !isNaN(c = ('' + a[i]).charCodeAt(0)))
    430 			n.push(c); // 跳過無法判讀的值
    431 	return eval('String.fromCharCode(' + n + ')');//n.join(',')	這樣較快
    432 }
    433 */
    434 };
    435
    436
    437
    438
    439
    440 CeL.data.native
    441 .
    442 /**
    443  * 對付有時 charCodeAt 會傳回 >256 的數值。
    444  * 若確定編碼是 ASCII (char code 是 0~255) 即可使用此函數替代 charCodeAt。
    445  * @param text	string
    446  * @param position	at what position
    447  * @return
    448  * @since	2008/8/2 10:10:49
    449  * @see
    450  * http://www.alanwood.net/demos/charsetdiffs.html
    451  * @memberOf	CeL.data.native
    452  */
    453 toASCIIcode=function (text, position) {
    454 	var _f = arguments.callee, c;
    455
    456 	if (!_f.t) {
    457 		// initial
    458 		var i = 129, t = _f.t = [], l = {
    459 			8364 : 128,
    460 			8218 : 130,
    461 			402 : 131,
    462 			8222 : 132,
    463 			8230 : 133,
    464 			8224 : 134,
    465 			8225 : 135,
    466 			710 : 136,
    467 			8240 : 137,
    468 			352 : 138,
    469 			8249 : 139,
    470 			338 : 140,
    471 			381 : 142,
    472 			8216 : 145,
    473 			8217 : 146,
    474 			8220 : 147,
    475 			8221 : 148,
    476 			8226 : 149,
    477 			8211 : 150,
    478 			8212 : 151,
    479 			732 : 152,
    480 			8482 : 153,
    481 			353 : 154,
    482 			8250 : 155,
    483 			339 : 156,
    484 			382 : 158,
    485 			376 : 159
    486 		};
    487 		for (; i < 256; i += 2)
    488 			t[i] = i;
    489 		for (i in l)
    490 			// sl(i+' = '+l[i]),
    491 			t[Math.floor(i)] = l[i];
    492 	}
    493
    494 	if (position < 0 && !isNaN(text))
    495 		c = text;
    496 	else
    497 		c = text.charCodeAt(position || 0);
    498
    499 	return c < 128 ? c : (_f.t[c] || c);
    500 };
    501
    502
    503 /*	2008/8/2 9:9:16
    504 	encodeURI, encodeURIComponent 僅能編成 utf-8，對於其他 local 編碼可使用本函數。
    505
    506 e.g.,
    507 f.src='http://www.map.com.tw/search_engine/searchBar.asp?search_class=address&SearchWord='+encodeUC(q[0],'big5')
    508
    509
    510
    511
    512 perl
    513 #use Encode qw(from_to);
    514 use Encode;
    515
    516 my $tEnc='utf-8';
    517
    518 $t="金";
    519
    520 $t=Encode::decode($t,'big5');
    521
    522 Encode::from_to($t,$lEnc,$outEnc);
    523
    524 Encode::from_to
    525
    526 @b=split(//,$a);
    527
    528 for($i=0;$i<scalar(@b);$i++){
    529  $r.=sprintf('%%%X',ord($b[$i]));
    530 };
    531
    532
    533 */
    534 //encodeUC[generateCode.dLK]='toASCIIcode';
    535 function encodeUC(u, enc) {
    536 	if (!enc || enc == 'utf8')
    537 		return encodeURI(u);
    538
    539 	var i = 0, c = new ActiveXObject("ADODB.Stream"), r = [];
    540 	// adTypeText;
    541 	c.Type = 2;
    542 	c.Charset = enc;
    543 	c.Open();
    544 	c.WriteText(u);
    545 	c.Position = 0;
    546 	c.Charset = 'iso-8859-1';
    547 	u = c.ReadText();
    548 	c.Close();
    549
    550 	for (; i < u.length; i++)
    551 		r.push((c = u.charCodeAt(i)) < 128 ? u
    552 				.charAt(i) : '%'
    553 				+ toASCIIcode(c, -1).toString(16)
    554 				.toUpperCase());
    555
    556 	return r.join('').replace(/ /g, '+');
    557 }
    558
    559
    560
    561
    562 CeL.data.native
    563 .
    564 /**
    565  * String pattern (e.g., "/a+/g") to RegExp pattern.
    566  * qq// in perl.
    567  * String.prototype.toRegExp = function(f) { return to_RegExp_pattern(this.valueOf(), f); };
    568  * @param {String} pattern	pattern text
    569  * @param {Boolean|String} [RegExp_flag]	flags when need to return RegExp object
    570  * @param {RegExp} [escape_pattern]	char pattern need to escape
    571  * @return	{RegExp} RegExp object
    572  */
    573 to_RegExp_pattern = function(pattern, RegExp_flag, escape_pattern) {
    574 	var r = pattern
    575 		// 不能用 $0
    576 		.replace(escape_pattern || /([.+*?|()\[\]\\{}])/g, '\\$1')
    577 		// 這種方法不完全，例如 /\s+$|^\s+/g
    578 		.replace(/^([\^])/, '\\^').replace(/([$])$/, '\\$');
    579 	return RegExp_flag ? new RegExp(r, /^[igms]+$/i.test(RegExp_flag) ? RegExp_flag : '') : r;
    580 };
    581
    582
    583
    584 CeL.data.native
    585 .
    586 /**
    587  * 重新設定 RegExp object 之 flag
    588  * @param {RegExp} regexp	RegExp object to set
    589  * @param {String} flag	flag of RegExp
    590  * @return	{RegExp}
    591  * @example
    592  * 附帶 'g' flag 的 RegExp 對相同字串作 .test() 時，第二次並不會重設。因此像下面的 expression 兩次並不會得到相同結果。
    593  * var r=/,/g,t='a,b';
    594  * WScript.Echo(r.test(t)+','+r.test(t));
    595  *
    596  * //	改成這樣就可以了：
    597  * var r=/,/g,t='a,b',s=renew_RegExp_flag(r,'-g');
    598  * WScript.Echo(s.test(t)+','+s.test(t));
    599  *
    600  * //	這倒沒問題：
    601  * r=/,/g,a='a,b';
    602  * if(r.test(a))alert(a.replace(r,'_'));
    603  *
    604  * //	delete r.lastIndex; 無效，得用 r.lastIndex=0; 因此下面的亦可：
    605  * if(r.global)r.lastIndex=0;
    606  * if(r.test(a)){~}
    607  *
    608  * @see
    609  * http://msdn.microsoft.com/zh-tw/library/x9h97e00(VS.80).aspx,
    610  * 如果規則運算式已經設定了全域旗標，test 將會從 lastIndex 值表示的位置開始搜尋字串。如果未設定全域旗標，則 test 會略過 lastIndex 值，並從字串之首開始搜尋。
    611  * http://www.aptana.com/reference/html/api/RegExp.html
    612  * @memberOf	CeL.data.native
    613  */
    614 renew_RegExp_flag = function(regexp, flag) {
    615 	var i, flag_set = {
    616 		global : 'g',
    617 		ignoreCase : 'i',
    618 		multiline : 'm'
    619 	};
    620
    621 	// 未指定 flag: get flag
    622 	if (!flag) {
    623 		flag = '';
    624 		for (i in flag_set)
    625 			if (regexp[i])
    626 				flag += flag_set[i];
    627 		return flag;
    628 	}
    629
    630 	var a = flag.charAt(0), F = '', m;
    631 	a = a === '+' ? 1 : a === '-' ? 0 : (F = 1);
    632
    633 	if (F)
    634 		// 無 [+-]
    635 		F = flag;
    636 	else
    637 		// f: [+-]~ 的情況，parse flag
    638 		for (i in flag_set)
    639 			if ((m = flag.indexOf(flag_set[i], 1) != -1) && a || !m
    640 					&& regexp[i])
    641 				F += flag_set[i];
    642
    643 	// for JScript<=5
    644 	try{
    645 		return new RegExp(regexp.source, F);
    646 	}catch (e) {
    647 		// TODO: handle exception
    648 	}
    649 };
    650
    651
    652 /*	2004/5/27 16:08
    653 	將 MS-DOS 萬用字元(wildcard characters)轉成 RegExp, 回傳 pattern
    654 	for search
    655
    656 usage:
    657 	p=new RegExp(turnWildcardToRegExp('*.*'))
    658
    659
    660 flag&1	有變化的時候才 return RegExp
    661 flag&2	add ^$
    662
    663
    664 萬用字元經常用在檔名的置換。
    665 * 代表任意檔案名稱
    666 如：ls * 表示列出所有檔案名稱。
    667 ? 則代表一個字元
    668 如: ls index.??? 表示列出所有 index.三個字元 的檔案名稱
    669 [ ] 代表選擇其中一個字元
    670 [Ab] 則代表 A 或 b 二者之中的一個字元
    671 如: ls [Ab]same 為 Asame 或 bsame
    672 [! ] 代表除外的一個字元
    673 [!Ab] 則代表 不是 A 且 不是 b 的一個字元
    674 如: [!0-9] 表不是數字字元
    675 如: *[!E] 表末尾不是 E 的檔名
    676
    677 memo:
    678 檔案名稱不可包含字元	** 不包含目錄分隔字元 [\\/]:
    679 /:*?"<>|/
    680
    681 */
    682
    683 //	萬用字元 RegExp source, ReadOnly
    684 turnWildcardToRegExp.w_chars = '*?\\[\\]';
    685
    686 function turnWildcardToRegExp(p, f) { // pattern, flag
    687
    688 	if (p instanceof RegExp)
    689 		return p;
    690 	if (!p || typeof p != 'string')
    691 		return;
    692
    693 	var ic = arguments.callee.w_chars, r;
    694 	if ((f & 1) && !new RegExp('[' + ic + ']').test(p))
    695 		return p;
    696
    697 	ic = '[^' + ic + ']';
    698 	r = p
    699 		//	old: 考慮 \
    700 		//.replace(/(\\*)(\*+|\?+|\.)/g,function($0,$1,$2){var c=$2.charAt(0);return $1.length%2?$0:$1+(c=='*'?ic+'*':c=='?'?ic+'{'+$2.length+'}':'\\'+$2);})
    701
    702 		//	處理目錄分隔字元：多轉一，'/' → '\\' 或相反
    703 		.replace(/[\\\/]+/g, typeof dirSp === 'string' ? dirSp : '\\')
    704
    705 		//	在 RegExp 中有作用，但非萬用字元，在檔名中無特殊作用的
    706 		.replace(/([().^$\-])/g, '\\$1')
    707
    708 		//	* 代表任意檔案字元
    709 		.replace(/\*+/g, '\0*')
    710
    711 		//	? 代表一個檔案字元
    712 		.replace(/\?+/g, function($0) {
    713 			return '\0{' + $0.length + '}';
    714 		})
    715
    716 		//	translate wildcard characters
    717 		.replace(/\0+/g, ic)
    718
    719 		//	[ ] 代表選擇其中一個字元
    720 		//pass
    721
    722 		//	[! ] 代表除外的一個字元
    723 		.replace(/\[!([^\]]*)\]/g, '[^$1]')
    724 		;
    725
    726
    727 	// 有變化的時候才 return RegExp
    728 	if (!(f & 1) || p !== r)
    729 		try {
    730 			p = new RegExp(f & 2 ? '^' + r + '$' : r, 'i');
    731 		} catch (e) {
    732 			//	輸入了不正確的 RegExp：未預期的次數符號等
    733 		}
    734
    735 	return p;
    736 }
    737
    738
    739
    740
    741 //	string & Number處理	-----------------------------------------------
    742
    743 //	set prototype's function of 內建物件 for 相容性(not good way..)
    744 //setTool[generateCode.dLK]='*setTool();';//,product,countS,to_fixed,getText,turnUnicode,trimStr,String_to_Date,Date_to_String,JSalert
    745 function setTool(){
    746  if(!String.prototype.x&&typeof product==='function')String.prototype.x=product;
    747  if(!String.prototype.count&&typeof countS==='function')String.prototype.count=countS;
    748  if(!Number.prototype.to_fixed&&typeof to_fixed==='function')Number.prototype.to_fixed=to_fixed;
    749  if(!String.prototype.gText&&typeof getText==='function')String.prototype.gText=getText;
    750  if(!String.prototype.turnU&&typeof turnUnicode==='function')String.prototype.turnU=turnUnicode;
    751  if(!String.prototype.trim&&typeof trimStr==='function')String.prototype.trim=trimStr;
    752  //	建議不用，因為在for(in Array)時會..
    753  //if(!Array.prototype.unique&&typeof Aunique==='function')Array.prototype.unique=function() { return uniqueArray(this); };
    754
    755  if(!String.prototype.toDate&&typeof String_to_Date==='function')String.prototype.toDate=String_to_Date;
    756  if(!Date.prototype.toStr&&typeof Date_to_String==='function')Date.prototype.toStr=Date_to_String;
    757  if(typeof alert=='undefined'&&typeof JSalert==='function')alert=JSalert;	//	在HTML中typeof alert=='object'
    758 }
    759
    760 // array,sortFunction
    761 function uniqueArray(a, f) {
    762 	if (f)
    763 		a.sort(f);
    764 	else
    765 		a.sort();
    766 	var i = 1, j = -1;
    767 	for (; i < a.length; i++)
    768 		if (a[i] == a[i - 1]) {
    769 			if (j < 0)
    770 				j = i;
    771 		} else if (j >= 0)
    772 			a.splice(j, i - j), i = j, j = -1;
    773 	if (j >= 0)
    774 		a.splice(j, i - j);
    775 	return a;
    776 }
    777
    778 function product(c) {
    779 	if (isNaN(c) || (c = Math.floor(c)) < 1)
    780 		return '';
    781 	var i, r = '', s = [];
    782 	s[i = 1] = this;
    783 	while (i + i <= c)
    784 		s[i + i] = s[i] + s[i], i += i;
    785 	while (c) {
    786 		if (i <= c)
    787 			r += s[i], c -= i;
    788 		i /= 2;
    789 	}
    790 	return r;//in VB:String(c,this)
    791 }
    792 //	計算string中出現k之次數	用s///亦可@perl
    793 function countS(k) { // k亦可用RegExp
    794 	//var c=0,s=this,i=0,l;if(k&&typeof k=='string'){l=k.length;while((i=this.indexOf(k,i))!=-1)c++,i+=l;}return c;
    795 	return (this.length - this.replace(k, '').length) / k.length;
    796 }
    797
    798
    799 CeL.data.native
    800 .
    801 /**
    802  * 取至小數 d 位，
    803  * 肇因： JScript即使在做加減運算時，有時還是會出現 1.4000000000000001、0.0999999999999998 等數值。此函數可取至 1.4 與 0.1。
    804  * c.f., round()
    805  * @param {Number} digits	1,2,..: number of decimal places shown
    806  * @param {Number} [max]	max digits	max===0:round() else floor()
    807  * @return
    808  * @see
    809  * https://bugzilla.mozilla.org/show_bug.cgi?id=5856
    810  * IEEE754の丸め演算は最も報告されるES3「バグ」である。
    811  * http://www.jibbering.com/faq/#FAQ4_6
    812  * http://en.wikipedia.org/wiki/Rounding
    813  * @example
    814  * {var d=new Date,v=0.09999998,i=0,a;for(;i<100000;i++)a=v.to_fixed(2);alert(v+'\n→'+a+'\ntime:'+format_date(new Date-d));}
    815  * @memberOf	CeL.data.native
    816  */
    817 to_fixed = function(digits, max) {
    818 	var v = this.valueOf(),
    819 	i, n;
    820
    821 	if (isNaN(v))
    822 		return v;
    823
    824 	if (isNaN(digits) || digits < 0)
    825 		// 內定：8位
    826 		digits = 8;
    827 	else if (digits > 20)
    828 		digits = 20;
    829
    830 	if (!max && Number.prototype.toFixed)
    831 		return parseFloat(v.toFixed(digits));
    832
    833 	if (v < 0)
    834 		// 負數
    835 		n = 1, v = -v;
    836 	if ((i = (v = v.toString(10)).indexOf('e')) !== -1)
    837 		return v.charAt(i + 1) == '-' ? 0 : v;
    838
    839 	//library_namespace.debug(v);
    840 	//	TODO: using +.5 的方法
    841 	//	http://clip.artchiu.org/2009/06/26/%E4%BB%A5%E6%95%B8%E5%AD%B8%E7%9A%84%E5%8E%9F%E7%90%86%E8%99%95%E7%90%86%E3%80%8C%E5%9B%9B%E6%8D%A8%E4%BA%94%E5%85%A5%E3%80%8D/
    842 	if ((i = v.indexOf('.')) !== -1) {
    843 		if (i + 1 + digits < v.length)
    844 			if (max)
    845 				v = v.slice(0, i + 1 + digits);
    846 			else {
    847 				v = '00000000000000000000' + Math.round(
    848 						v.slice(0, i++) + v.substr(i, digits) + '.'
    849 						+ v.charAt(i + digits)).toString(10);
    850 				// (v!=0?alert(v+','+v.length+','+digits+','+v.substr(0,v.length-digits)+','+v.substr(max)):0);
    851 				v = v.slice(0, max = v.length - digits) + '.' + v.substr(max);
    852 			}
    853 	}
    854
    855 	return v ? parseFloat((n ? '-' : '') + v) : 0;
    856 };
    857 /*	old:very slow
    858 function to_fixed(d,m){
    859  var v=this.valueOf(),i;if(isNaN(v))return v;
    860  if(isNaN(d)||d<0)d=8;	//	內定：8位
    861  if(!m){
    862   v=Math.round(Math.pow(10,d)*v);v=v<0?'-'+'0'.x(d)+(-v):'0'.x(d)+v;
    863   v=v.slice(0,i=v.length-d)+'.'+v.substr(i);
    864  }else if(i=(v=''+v).indexOf('.')+1)v=v.slice(0,i+(d?d:d-1));
    865  return parseFloat(v||0);
    866 }
    867 */
    868
    869 /*
    870 //	增添單位
    871 var addDenominationSet={};
    872 addDenominationSet.a=',,,,'.split(',');
    873 function addDenomination(a,b){
    874
    875 }
    876 */
    877
    878
    879
    880
    881 //var sourceF=WScript.ScriptName,targetF='test.js';simpleWrite('tmp.js',alert+'\n'+simpleRead+'\n'+simpleWrite+'\nvar t="",ForReading=1,ForWriting=2,ForAppending=8\n,TristateUseDefault=-2,TristateTrue=-1,TristateFalse=0\n,WshShell=WScript.CreateObject("WScript.Shell"),fso=WScript.CreateObject("Scripting.FileSystemObject");\nt='+dQuote(simpleRead(sourceF),80)+';\nsimpleWrite("'+targetF+'",t);//eval(t);\nalert(simpleRead("'+sourceF+'")==simpleRead("'+targetF+'")?"The same (test dQuote OK!)":"Different!");');//WshShell.Run('"'+getFolder(WScript.ScriptFullName)+targetF+'"');
    882 //	determine quotation mark:輸入字串，傳回已加'或"之字串。
    883 /*
    884 dQuote.qc=function(c,C){
    885 	return c<32?'\\'+c:C;
    886 };
    887 */
    888 function dQuote(s,len,sp){	//	string,分割長度(會採用'~'+"~"的方式),separator(去除末尾用)
    889  var q;s=String(s);if(sp)s=s.replace(new RegExp('['+sp+']+$'),'');	//	去除末尾之sp
    890  if(isNaN(len)||len<0)len=0;
    891  if(len){
    892   var t='';
    893   for(;s;)t+='+'+dQuote(s.slice(0,len))+'\n',s=s.substr(len);	//	'\n':NewLine
    894   return t.substr(1);
    895  }
    896  //if(len){var t='';for(;s;)t+='t+='+dQuote(s.slice(0,len))+'\n',s=s.substr(len);return t.substr(3);}	//	test用
    897  s=s.replace(/\\/g,'\\\\')
    898 	.replace(/\r/g,'\\r').replace(/\n/g,'\\n')	//	\b,\t,\f
    899 	//	轉換控制字符
    900 	.replace(/([\0-\37\x7f\xff])/g,function($0,$1){var c=$1.charCodeAt(0);return c<64?'\\'+c.toString(8):'\\x'+(c<16?'0':'')+c.toString(16);})
    901 	//.replace(/([\u00000100-\uffffffff])/g,function($0,$1){})
    902 	;
    903  //q=s.length;while(s.charAt(--q)==sp);s=s.slice(0,q+1);
    904  if(s.indexOf(q="'")!=-1)q='"';
    905  if(s.indexOf(q)!=-1)s=s.replace(new RegExp(q="'",'g'),"\\'");	//	,alert("Can't determine quotation mark, the resource may cause error.\n"+s);
    906  return q+s+q;
    907 }
    908
    909
    910 CeL.data.native
    911 .
    912 /**
    913  * check input string send to SQL server
    914  * @param {String} string	input string
    915  * @return	{String}	轉換過的 string
    916  * @since	2006/10/27 16:36
    917  * @see
    918  * from lib/perl/BaseF.pm (or program/database/BaseF.pm)
    919  * @memberOf	CeL.data.native
    920  */
    921 checkSQLInput = function(string) {
    922 	if (!string)
    923 		return '';
    924
    925 	// 限制長度
    926 	if (maxInput && string.length > maxInput)
    927 		string = string.slice(0, maxInput);
    928
    929 	return string
    930 		// for \uxxxx
    931 		.replace(/\\u([\da-f]{4})/g, function($0, $1) {
    932 			return String.fromCharCode($1);
    933 		}).replace(/\\/g, '\\\\')
    934
    935 		// .replace(/[\x00-\x31]/g,'')
    936 		.replace(/\x00/g, '\\0')
    937
    938 		// .replace(/\x09/g,'\\t')
    939 		// .replace(/\x1a/g,'\\Z')
    940
    941 		// .replace(/\r\n/g,' ')
    942 		.replace(/\r/g, '\\r').replace(/\n/g, '\\n')
    943
    944 		// .replace(/"/g,'\\"')
    945 		.replace(/'/g, "''");
    946 };
    947
    948 /**
    949  * check input string send to SQL server 並去掉前後 space
    950  * @param {String} string	input string
    951  * @return	{String}	轉換過的 string
    952  * @since	2006/10/27 16:36
    953  * @see
    954  * from lib/perl/BaseF.pm (or program/database/BaseF.pm)
    955  * function strip() @ Prototype JavaScript framework
    956  * @memberOf	CeL.data.native
    957  */
    958 function checkSQLInput_noSpace(string) {
    959 	return string ? checkSQLInput(string
    960 			// .replace(/[\s\n]+$|^[\s\n]+/g,'')
    961 			.replace(/^\s+|\s+$/g, ''))
    962 		: '';
    963 }
    964 ;
    965 /*
    966
    967 2010/6/1
    968 test time:
    969
    970 '   fhdgjk   lh gjkl ;sfdf d  hf gj '
    971
    972 .replace(/^\s+|\s+$/g, '')
    973 ~<
    974 .replace(/\s+$|^\s+/g, '')
    975 <
    976 .replace(/^\s+/, '').replace(/\s+$/, '')
    977 ~<
    978 .replace(/\s+$/, '').replace(/^\s+/, '')
    979
    980 */
    981
    982
    983
    984 CeL.data.native
    985 .
    986 /**
    987  * 轉換字串成數值，包括分數等。分數亦將轉為分數。
    988  * @param {String} number	欲轉換之值
    989  * @return
    990  * @memberOf	CeL.data.native
    991  */
    992 parse_number = function(number) {
    993 	var m = typeof number;
    994 	if (m === 'number')
    995 		return number;
    996 	if (!number || m !== 'string')
    997 		return NaN;
    998
    999 	number = number.replace(/(\d),(\d)/g, '$1$2');
    1000 	if (m = number.match(/(-?[\d.]+)\s+([\d.]+)\/([\d.]+)/)) {
    1001 		var p = parseFloat(m[1]), q = parseFloat(m[2]) / parseFloat(m[3]);
    1002 		return p + (m[1].charAt(0) === '-' ? -q : q);
    1003 	}
    1004 	if (m = number.match(/(-?[\d.]+)\/([\d.]+)/))
    1005 		// new quotient(m[1],m[2])
    1006 		return parseFloat(m[1]) / parseFloat(m[2]);
    1007
    1008 /*
    1009 	try {
    1010 		return isNaN(m = parseFloat(number)) ?
    1011 				//	TODO: security hole
    1012 				eval(number) : m;
    1013 	} catch (e) {
    1014 		return m;
    1015 	}
    1016 */
    1017 };
    1018
    1019
    1020
    1021 return (
    1022 	CeL.data.native
    1023 );
    1024 }
    1025
    1026
    1027 });
    1028
    1029