2010-10-07 86 views
1

我試圖在PHP中創建一個函數,用於評估數學表達式 - 包括諸如sin,cos等函數。我的方法是刪除所有字符不是數字,數學運算符或數學函數,然後在eval()中使用該字符串。問題在於我對正則表達式不夠了解,無法在同一表達式中否定字符和短語。排除列表中的所有字符而不是列表中的短語

到目前爲止,這是我有:

$input = preg_replace("/[^0-9+\-.*\/()sincota]/", "", $input); 

顯然,字符正弦,餘弦,和棕褐色可以按任意順序輸入表達式中使用(而不是隻允許短語sin,cos和tan)。如果我進一步擴展此功能以包含更多的字符和函數,則會帶來更大的安全風險,因爲惡意用戶可以通過與應用程序的巧妙交互來執行任何PHP命令。

誰能告訴我如何解決我的正則表達式並消除這個問題?

+0

嗯,還有一個原因,大多數語言拋出語法錯誤而不是嘗試一個最好的猜測,這樣瘋狂的謊言(你必須要在某些情況下是非常好的猜測)。你的解決方案仍然是一個解析器,而不是正則表達式(實際上,這並不困難),並且不用擔心執行任何PHP命令。 'eval = -evil'(在大多數情況下...) – Wrikken 2010-10-07 17:07:45

+1

http://en.wikipedia.org/wiki/Shunting_yard_algorithm – Wrikken 2010-10-07 17:11:01

+0

謝謝,Wrikken。過去十年我沒有看到這種情況,並且(相當不方便)忘記了這一點。我想我必須編寫一個解析器,而不是試圖用快速解決方案逃脫。 – 2010-10-07 17:21:46

回答

1

我試圖使 PHP函數,將評估的數學表達式 - 包括功能,如 正弦,餘弦等

也許我建議採取了多年的優勢已被輸入PHPExcel的工作已包含公式分析器。

它包括cos,sin和其他數百人。

否則,而不是否定,你可以看看積極的比賽:

$matches = array(); 
preg_match_all("#([0-9,/\*()+\s\.-]|sin|cos)+#", 'sin(12) + cos(13.5/2) evddal * (4-1)', $matches); 
echo implode('', $matches[0]); 

/* output: 
sin(12) + cos(13.5/2) * (4-1) 
*/ 
0

你可以試試這個:

preg_replace("/(sin|cos|tan)?[^0-9+\\.*\/()-]/", "$1", $input); 

code on ideone.com

但如果你試圖解析表達式來評價的話,我建議你解析它,而不是簡單地傳遞它通過正則表達式模式。

相關問題