2011-03-04 56 views
4

正則表達式可以替換替換涉及所謂標記表達式匹配的模式JavaScript,RegExp - 用涉及標記表達式的評估表達式替換?

例子:

var s = "... some string with full things..."; 
s = s.replace(/(some|full)/gi, "\"aw$1\"); 

這將導致

'... "awsome" string with "awfull" things...' 

和生活都很酷,因爲一些完全匹配,替換的條帶中的$ 1 g反映匹配的帶標記的表達式在大括號中,在這種情況下 - 恰好只有一些完整

現在,我們得到的想法 - 我在尋找一個主意,請執行以下操作:

字符串之前:

"{timeOfEffect: 259200}" 

字符串後
"{timeOfEffect: 3*24*60*60 }" 

值(60秒* 60分* 24小時)* 3 => 3天(不要問客戶的要求),但是用計算機術語閱讀它們在幾秒鐘內即可達到259200,並且可能包含該模式的許多發生。

我想創建一個替換表達式,它將$ 1和$ 2相乘,甚至將$ 1和$ 2傳遞給一個函數,或者將$ 1 * $ 2傳遞給一個評估上下文,但是我必須爲它創建一個函數,手動做。

我得到的最接近是

var x = /([0-9]*)\s\*\s([0-9]*)/g 
    , r = function(m){ 
      return m[1] * m[2]; 
     } 
while (m = x.exec(s)) 
    s = s.replace(x, r(m)); 

真遜一點點,因爲exec回報只是第一場比賽。 在REPLACE語句處理完後 - 下一個搜索再次從字符串的開頭開始 - 這是60K長度的字符串...

一個很好的解決方案將是下列之一: 一)進行匹配b)提供一個替換表達式,允許評估

另一種方法是對字符串進行標記,並以字節爲單位進行處理 - 這是對字符串的完全替代方法RegExp這將需要大量的代碼和努力,在這種情況下,我只會生活在性能損失或更好的戰鬥更好的替代這種需求...

幫助任何人?

回答

6
var s = "timeOfEffect: 3*24*60*60 var: 6*8 "; 
var r = new RegExp("([0-9*+-/]{0,}[0-9])","g"); 
s = s.replace(r,function(match){ return eval(match); }); 
alert(s) 
+0

哇。這個很酷!對reg-exp做一些調整 - 它涵蓋了所有基本算術(假設它們在語法上是正確的)! - 拉德加斯特布朗0秒前編輯 – 2011-03-07 11:53:24

+1

好的,這是最終的解決方案。 它可以很容易地擴展到支持大括號,但我不需要任何。 原始報價的問題在於它也與簡單數字相匹配 - 不需要更換。 'var r = new RegExp(「([0-9 \\。] +)([\\ * + - \\ /]。)([0-9 \\ * + - \\ /] +)( [0-9])「,」g「);' 'r =函數(m,m1,m2,m3,m4){' ''{ m3 + m4)' '} catch(ex){' 'return':\「@@ EVAL_ERROR:」+ m1 + m2 + m3 + m4 +「\」「' ''' '}' ' }'' S = s.replace(X,R)' 輸出顯然是針對 「@@ EVAL_ERROR」 檢查,併發送有關斷配置郵件... 謝謝:) – 2011-03-07 12:40:10

+0

嘿kewwwwwlll!匹配函數的前一個參數是搜索字符串中的匹配索引,最後一個參數是整個搜索字符串本身!它該死的快! 我可以用它來向編輯發出準確的解析錯誤! :) – 2011-03-07 13:14:21

4
var str = '{timeOfEffect: 3*24*60*60}, {timeOfEffect: 1+7}, {timeOfEffect: 20-3}, {timeOfEffect: 3/0}'; 

var result = str.replace(/\s([\d\/\*\-\+\s]+?)\}/g, function(all, match) { 
    return eval(match) + '}'; 
}); 

document.body.innerHTML = result; 
// {timeOfEffect:259200}, {timeOfEffect:8}, {timeOfEffect:17}, {timeOfEffect:Infinity} 

jsFiddle

eval()是安全的使用,因爲我們已確保該字符串只包含0-9\n\t/*-+I was hoping有可能是像Math.parse(),但沒有。

如果您需要更復雜的數學需要圓括號,只需將轉義()添加到正則表達式字符範圍。