前天写了一个"JScript版的String.Format方法",本来都已经使用遍历法来替换格式化字符串了,结果却使用了RegExp和substr之类的憋脚方法。后来问题男很热心的给出了一个全扫描的方案,更郁闷的是由于自己对测试的认识不足,居然只使用了期望数据来测试代码,搞得bug一大坨单扫描的JScript版String.Format方法

    于是在问题男的建议基础上,自己又作了一些优化,把整个替换操作一次扫描高定。代码如下: 
单扫描的JScript版String.Format方法 // StringHelper.Format('{0}, {2}, {1}', 'abc', 'def', 'ghi');
单扫描的JScript版String.Format方法 //
 return "abc, ghi, def".
单扫描的JScript版String.Format方法 
StringHelper.Format = function(format)
单扫描的JScript版String.Format方法 {
单扫描的JScript版String.Format方法    
if ( arguments.length == 0 )
单扫描的JScript版String.Format方法    {
单扫描的JScript版String.Format方法        
return '';
单扫描的JScript版String.Format方法    }
单扫描的JScript版String.Format方法    
if ( arguments.length == 1 )
单扫描的JScript版String.Format方法    {
单扫描的JScript版String.Format方法        
return String(format);
单扫描的JScript版String.Format方法    }
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法    
var strOutput = '';
单扫描的JScript版String.Format方法    
for ( var i=0 ; i < format.length-1 ; )
单扫描的JScript版String.Format方法    {
单扫描的JScript版String.Format方法        
if ( format.charAt(i) == '{' && format.charAt(i+1!= '{' )
单扫描的JScript版String.Format方法        {
单扫描的JScript版String.Format方法            
var index = 0, indexStart = i+1;
单扫描的JScript版String.Format方法            
for ( var j=indexStart ; j <= format.length-2 ; ++j )
单扫描的JScript版String.Format方法            {
单扫描的JScript版String.Format方法                
var ch = format.charAt(j);
单扫描的JScript版String.Format方法                
if ( ch < '0|| ch > '9' ) break;
单扫描的JScript版String.Format方法            }
单扫描的JScript版String.Format方法            
if ( j > indexStart )
单扫描的JScript版String.Format方法            {
单扫描的JScript版String.Format方法                
if ( format.charAt(j) == '}' && format.charAt(j+1!= '}' )
单扫描的JScript版String.Format方法                {
单扫描的JScript版String.Format方法                     
for ( var k=j-1 ; k >= indexStart ; k-- )
单扫描的JScript版String.Format方法                     {
单扫描的JScript版String.Format方法                         index 
+= (format.charCodeAt(k)-48)*Math.pow(10, j-1-k);
单扫描的JScript版String.Format方法                     }  
单扫描的JScript版String.Format方法                    
var swapArg = arguments[index+1];
单扫描的JScript版String.Format方法                    strOutput 
+= swapArg;
单扫描的JScript版String.Format方法                    i 
+= j-indexStart+2;
单扫描的JScript版String.Format方法                    
continue;
单扫描的JScript版String.Format方法                }
单扫描的JScript版String.Format方法            }
单扫描的JScript版String.Format方法            strOutput 
+= format.charAt(i);
单扫描的JScript版String.Format方法            i
++;
单扫描的JScript版String.Format方法        }
单扫描的JScript版String.Format方法        
else
单扫描的JScript版String.Format方法        {
单扫描的JScript版String.Format方法            
if ( ( format.charAt(i) == '{' && format.charAt(i+1== '{' )
单扫描的JScript版String.Format方法                
|| ( format.charAt(i) == '}' && format.charAt(i+1== '}' ) )
单扫描的JScript版String.Format方法            {
单扫描的JScript版String.Format方法                i
++
单扫描的JScript版String.Format方法            }
单扫描的JScript版String.Format方法            strOutput 
+= format.charAt(i);
单扫描的JScript版String.Format方法            i
++;
单扫描的JScript版String.Format方法        }
单扫描的JScript版String.Format方法    }
单扫描的JScript版String.Format方法    strOutput 
+= format.substr(i);
单扫描的JScript版String.Format方法    
return strOutput;
单扫描的JScript版String.Format方法 }    

    相对上一版本的改进:
    1、不再使用RegExp和substr|substring;
    2、一次扫描完成所有替换和转义;
    3、修复了对"}}"扫描未做正确处理的bug;
    4、修复了取格式化条目编号可能出错的bug。

    新的测试数据:
单扫描的JScript版String.Format方法 alert(StringHelper.Format('{0}', 'abc'));
单扫描的JScript版String.Format方法 alert(StringHelper.Format('{
0}}{0}, {{2}, {1}}', 'abc', 'def', 'ghi'));    
单扫描的JScript版String.Format方法 alert(StringHelper.Format('{
000}, {{{{2}}}}, {001}', 'abc', 'def', 'ghi'));    
单扫描的JScript版String.Format方法 alert(StringHelper.Format('{{
0}}\r\n2, {2}\r\n, {1}', 'abc', 'def', 'ghi'));    
单扫描的JScript版String.Format方法 alert(StringHelper.Format('{
0}{0}{0}, {0{1}0}, {{{{{2}}}', 'abc', 'def'));

    测试所得结果:
单扫描的JScript版String.Format方法 No.1 alert: abc
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法 No.2 alert: {0}abc, {2}, {1}
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法 No.3 alert: abc, {{2}}, def
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法 No.4 alert: {
0}单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法                2, ghi单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法                , def
单扫描的JScript版String.Format方法
单扫描的JScript版String.Format方法 No.5 alert: abcabcabc, {0def0}, {{{2}}

    继续征集更优化方案:)

    BTW: 代码中使用了一个JavaScript的Syntax Sugar来减少代码,你看循环:
单扫描的JScript版String.Format方法 for ( var i=0 ; i < format.length-1 ; )
单扫描的JScript版String.Format方法 {
单扫描的JScript版String.Format方法    
if ( ... )
单扫描的JScript版String.Format方法    {
单扫描的JScript版String.Format方法        
// . . .
单扫描的JScript版String.Format方法
    }
单扫描的JScript版String.Format方法    
else
单扫描的JScript版String.Format方法    {
单扫描的JScript版String.Format方法        format.charAt(i
+i)
单扫描的JScript版String.Format方法    }
单扫描的JScript版String.Format方法 }

    显然i+1已经溢出了字符串的长度了,不过这时根本不用管它,JavaScript会返回一个undefined,这个值完全不会影响我们的程序逻辑。如果是C#就需要啰里啰唆的去判断i+1是不是小于format.length,否则就Index Out of Range Exception了单扫描的JScript版String.Format方法

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-24
  • 2021-07-25
  • 2021-07-16
  • 2022-12-23
猜你喜欢
  • 2022-03-04
  • 2021-07-29
  • 2021-12-24
  • 2021-12-01
  • 2021-05-27
  • 2021-08-14
相关资源
相似解决方案