Re: [問題] javascript執行問題
※ 引述《shomingchang ( )》之銘言:
: <script>
: var calculate_sqrt_patt=/\(Math.sqrt\(\d+\)\)/g;
: var metPatt;
: calculate_sqrt_patt.compile(calculate_sqrt_patt);
: var CurrentResult="(Math.sqrt(121))+(Math.sqrt(25))+(Math.sqrt(81))+
: (Math.sqrt(144))+(Math.sqrt(169))+(Math.sqrt(49))";
:
: while((metPatt=calculate_sqrt_patt.exec(CurrentResult))!=null)
: {
: var replaceString;
: var str=metPatt.toString();
: alert(CurrentResult+":\n"+str);
: replaceString=eval(str).toString();
: CurrentResult=CurrentResult.replace(str,replaceString);
: }
在Bugzilla裡面,這個問題(其實不是Bug)已經存在將近10年了!
看了一下討論串,好像每年至少都會有一兩個人回報這個現象!
簡單來說,就是Regular Expression裡面的g(global)這個選項有被開啟的話,
這個RegExp物件裡的lastIndex就會將每次parse時的字串位置記錄下來。
這樣會使下次在使用這個RegExp物件搜尋字串時(不限是否相同字串),不會重複搜尋。
注意,RegExp裡的lastIndex並不會因為丟進新的String就重頭開始搜尋!
用原PO附的程式碼舉例來說,
第一輪RegExp執行exec()之後,matPatt會得到"(Math.sqrt(121))",
然後calculate_sqrt_patt.lastIndex會等於16,也就是(Math.sqrt(121))最後的)位置。
由於原PO將(Math.sqrt(121))替換成執行結果11,造成字串被改變,
所以calculate_sqrt_patt.lastIndex就會改指向"(Math.sqrt(25))"的5的位置,
"(Math.sqrt(25))"就被忽略掉了。程式繼續執行下去就會有跳一格資料的感覺。
總的來說,解決辦法有兩種:
1) 將RegExp物件的g參數去掉,這樣不會記錄lastIndex,這值永遠是0。
2) 每一輪迴圈都執行:calculate_sqrt_patt.lastIndex = 0;
把lastIndex歸零,就會重頭開始。
不過第一種似乎比較推薦 :)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.113.247.149
→
05/14 06:46, , 1F
05/14 06:46, 1F
推
05/14 14:36, , 2F
05/14 14:36, 2F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):