字元型中文算式轉英文標準算式的方法?

  程式在接受使用者輸入算式時,或者你有一個字元型算式,它可能不是標準的英文字元型算式,在轉化成可計算的算式之前,我們要把它標準化。方法是有很多,如:窮盡式逐項替換法、分離字串逐一替換法、正則表示式替換方法、自定義字典替換法、自定義“類”之一勞永逸法……還要避開一些暗含陷阱的方法。效果圖0:

     

   

字元型中文算式轉英文標準算式的方法

工具/原料

as3.0

步驟/方法

  為了方便,我們先定義一個變數,並給它一個值——中文字元型算式:

   var formula:String="{[[[(20+3)*5]]]-10-2.5}/ 2.5×(1134-500÷4)=";

  我們需要的效果是:

    var result:String="(((((20+3)*5)))-10-2.5)/2.5*(1134--500/4)”;

  實現的方法細述如下:

窮盡式逐項替換法。

  窮盡可能出現的情況,再用正則表示式匹配一個或多個替換項。因為字元型中文算式可能出現的情況為數不多,可以很容易地列舉。

 function replace(str:String ):String {

  formula = str.replace(/[\[\{{[(]/g,"(")//統一為英文左括號

  str = str.replace(/[\]\}}])]/g,")")//統一為英文右括號

  str = str.replace(/×/g,"*");

  str= str.replace(/÷/g,"/");

   str= str.replace(/[== ]/g,"");//去掉空格和等號

   str= str.replace(/./g,".");

   str= str.replace(/0/g,0);

  str= str.replace(/1/g,1);

   str= str.replace(/2/g,2);

   str= str.replace(/3/g,3);

   str= str.replace(/4/g,4);

   str= str.replace(/5/g,5);

   str= str.replace(/6/g,6);

   str= str.replace(/7/g,7);

   str= formula.replace(/8/g,8);

  formula= formula.replace(/9/g,9);

   return str

 }

  測試一下:

   trace(formula=replace(formula));

  結果是符合要求的:

   (((((20+3)*5)))-10-2.5)/2.5*(1134-500/4)

  如果把替換與被替換的內容估成陣列,使用迴圈賦值,豈不可以大大簡化程式碼?我們試下:

varsymbol:Array=["+","-","*","/","(",")","(",")","(",")","(",")","(",")",".","0","1","2","3","4","5","6","7","8","9","","","",""];

var char:Array=["+","-","×","÷","(",")","[","]","[","]","{","}","{","}",".","0","1","2","3","4","5","6","7","8","9","=","="," ","",];

//...標準化算式...去中文字元、等號、空格...................

function replace(str:String ):String {

var k:uint=symbol.length;

for (var j:uint =0; j

str=str.replace(char[j],symbol[j]);

}

return str;

}

  測試一下:

  trace(formula=replace(formula));

  可惜呀,重複的字元中後面的中文字元不能替換掉:

  ((([(20+3)*5))]-10-2.5)/2.5*(1134-500/4)

  看到了吧,問題在這:“1134-500”,第二個“1”和第二個“0”都沒有被替換掉。但這個帶有陷阱的方法,仍叫人怦然心動!在它啟發下,我寫出了下面的方法。

分離字串逐一替換法。

  仍舊利用上面的兩個陣列做為替換與被替換的內容。構建帶有引數、有返回值的函式如下:

  //...標準化算式...去中文字元、等號、空格.....replace:替換..............

function replace(str:String ):String {

varstring:String="";

vark:uint=symbol.length;

varn:uint=str.length;

for(var t:uint =0; t

vars:String=str.charAt(t);

for(var j:uint =0; j

s=s.replace(char[j],symbol[j]);//…………注意這句……..

}

string+=s;

}

returnstring;

}

  可能有人會疑惑不解:出現相同的中文字元,不是可以用正則表示式中的標誌“/g”來匹配一個或者多個替換項嗎?問題是:正則表示式的模式不支援變數!!下面這樣是行不通的:

str=str.replace(/char[j] /g,symbol[j]);

  如果能行的話,我是不會使用分離字串這個方法的。

自定義字典替換法。

  你有過“暴力破解”共享軟體的經歷嗎?如果有過,那你一定知道“字典工具”。下面我們模擬“字典工具”做一個格式化算式的函式。在思想上,就是把中文算式看作是一個有序的密碼,通過我們的編碼字典來解釋它,還原它的本來面目。有趣吧?

var formula:String="{[[[(20+3)*5]]]-10-2.5}/ 2.5×(1134-500÷4)=";

varsymbol:Array=["+","-","*","/","(",")","+","-","*","/","(",")","(",")","(",")","(",")","(",")",".","0","1","2","3","4","5","6","7","8","9",".","0","1","2","3","4","5","6","7","8","9","","","",""];//謎底

var char:Array=["+","-","×","÷","(",")","+","-","*","/","(",")","[","]","[","]","{","}","{","}",".","0","1","2","3","4","5","6","7","8","9",".","0","1","2","3","4","5","6","7","8","9","=","="," ",""];//謎面

var dic:Array=[];//字典

function makeDic() {//製作字典

vark:uint=symbol.length;

for(var t:uint =0; t

dic[char[t]]=symbol[t];//編碼

}

}

makeDic();//製作

//...標準化算式...去中文字元、等號、空格.....replace:替換..............

function replace(str:String ):String {

varstring:String="";

vark:uint=str.length;

for(var j:uint =0; j

string+=dic[str.charAt(j)];//使用字典

}

returnstring;

}

測試一下:

trace(formula=replace(formula));

結果多麼令人歡欣鼓舞:

(((((20+3)*5)))-10-2.5)/2.5*(1134-500/4)

自定義“類”之一勞永逸法。

  上面三種都是成熟的程式碼,都可以封裝成類。以第三個辦法為例:

  這個類:在Lir包中,類名:Formula;建構函式為空;靜態方法:replace,有一個引數,接受字元型中文算式。函式有返回值:英文字元型標準算式。

  有了這個類,實在是太好了,應用起來大大地方便了。在時間軸上輸入下面的程式碼:

  import Lir .Formula

  var formula:String="{[[[(20+3)*5]]]-10-2.5}/ 2.5×(1134-500÷4)=";

  trace(Lir.Formula.replace(formula)); //呼叫類中的方法

  就這上面這一點程式碼?對,就這一點程式碼!快執行程式,看下輸出的結果:

        (((((20+3)*5)))-10-2.5)/2.5*(1134-500/4)

  我們又見到了這個早已熟悉的標準算式了!哈哈哈……我們都可以開心地笑了……

               來自實踐的體會絕對原創的經驗

                   作者:張志晨

                    2012.5.6

字元型中文算式轉英文標準算式的方法

相關問題答案