2012-04-15 34 views
0

假設我有表示爲一個字符串的函數表達式我如何在函數聲明字符串匹配「obj.foo」

"var someFunction = function (foo) { foo.bar = 'hello'; };" 

我怎麼能識別所有有效的(在JS語法方面)爲foo引用.bar安全地在那個字符串中?

即避免像"catfoo.barbar"這樣的實例我想用別的東西替換這些引用。

(但有人肯定要問...是我使用eval了,是它讓我的使用案例的意義)


我真的尋找的最重要的事情是如何匹配有效的對象名稱。我如何匹配對象名稱中所有有效字符的集合?他們甚至是什麼?像áéíóú這樣的字符顯然是有效的字符,所以它比[0-9a-zA-Z_]

要複雜一點來說明我真正想要做的事情。我有一個功能,我注入物體的屬性

function shader(src, dst, out) { 
    out.a = (src.a + dst.a)/2; 
} 

這將得到調用的每個像素在2D畫布上。我想要做的就是內聯這個函數,並以合理的方式刪除所有的點運算符。

... 
var src = {}, dst = {}, out = {}; 
... 

for (i = 0; i < len; i += 4) { 
    shader(src, dst, out); 
} 

內聯着色後變成

... 
var src = {}, dst = {}, out = {}; 
... 

for (i = 0; i < len; i += 4) { 
    out.a = (src.a + dst.a)/2; 
} 

但我也想去掉點運算符。我真的不確定會有什麼性能提升,它可能是無用的微型優化。內聯函數至少可以使FF中的性能提高100%。無論如何,我很好奇如何去做。原有的功能存在回退和易於定義。

+1

出於好奇,你使用'eval()'的用例是什麼? – Bojangles 2012-04-15 22:40:46

+1

正則表達式是不可能的。 JS比正則表達式可以處理的複雜程度更高。 – 2012-04-15 22:44:27

+0

我想內聯一個在單個像素上運行的函數調用。基本上我正在編譯2D畫布的像素着色器函數。調用每個像素的函數的開銷很大(在我嘗試的一些實現上),所以我試圖內聯函數調用。 – 2012-04-15 22:45:57

回答

1

這裏是用JavaScript編寫的一個JavaScript分析器:https://github.com/douglascrockford/JSLint/blob/master/jslint.js

它會產生一個很好的解析樹。祝你好運。

+0

我尊重這一點,一般來說,使用正則表達式本質上是解析一種不規則的語言是錯誤的,但我確實認爲我可以用比將整個表達式解析爲標記更簡單的方式來實現我所需要的。我不認爲jslint可以完全解析所有有效的語法。它不理解我使用捕獲(如果EvalError實例) – 2012-04-15 23:39:36

+0

你可以很安全地用一個正則表達式來查看(看看它在查找patternd之前還是之後,但不匹配它)。我已經爲您的案例創建了一個,並且通過eplaination瞭解如何使用它(或者如果需要,可以修改它)。請使用正則表達式請求進一步的幫助。 – JotaBe 2012-04-16 11:06:46

0

可以使用該正則表達式:

/(?=[{\s])foo.bar(?=[\s])/ 

用與string.replace,像這樣:

var replaced = original.replace(/(?=[{\s])foo.bar(?=[\s=])/g, "replacement"); 

括號[\s{]之間的第一組中,發現有{或間隔字符(空格,製表,等等)在foo之前。第二組[\s=]找到間隔字符或等號後的小節。如果您發現有其他可能性,您可以更改它。 (?=...)匹配一個字符串,但不包括它在匹配中。這意味着可以找到間距字符或大括號或等號,但不包含在匹配中,因此不會被替換。

最後的/g表示找到所有匹配項。如果你知道只有一個,你可以省略它。

+0

那麼''var var someFunction = function(foo){/ *設置foo.bar爲hello */foo.bar ='hello';};「'? – 2012-04-15 23:04:37

+0

nah我放棄了.. – Dale 2012-04-15 23:11:52

+0

我不知道OP的要求究竟是哪一個,但即使在這個示例(和極端情況)中,替換這個文本也不會造成危害,因爲調用了eval '相同或不同的評論將是一樣的。你甚至可以爭辯說它可能在「或」之間,那麼,是的,它會失敗,但在實際情況下,這種情況是否可能呢?OP應該告訴我們(但我想這是不可能的)。你看起來更像是一個數學家,理論化程序員以最簡單的方式解決問題,我認爲你使用大炮來殺死蚊子 – JotaBe 2012-04-16 09:59:56