2013-07-29 69 views
1

我有一個來自客戶端的參數字符串。一個例子可以是:從字符串評估自定義布爾表達式

串PARAM = 「(AND NAME.FULLNAME DOB.OPTIONAL)OR(ID和DOB.REQUIRED)OR(ID和國家)」

現在,我已經解析出所有傳入數據並具有代表每個參數的布爾值。

像:

bool name_FullName = true; 
bool dob_Optional = false; 

我試圖找到評估客戶的參數表達式爲真或假的最佳方式。

我想只是用他們的真/假布爾替換參數。然後找到任何TRUE AND TRUE並刪除它們,並用false替換TRUE AND FALSE。然後評估我已經離開的OR表達式。

打字後,這似乎是一個好方法。有沒有人有更快的解決方案,我錯過了?

+0

確保您捕捉括號,太 - 除非它總是(AND..AND..AND)OR(AND..AND ...)或者...... –

+0

你有沒有看使用的一個codeplex上的布爾分析器? http://stackoverflow.com/q/5029699/2270839 – Kevin

+1

有關解決方案的一些注意事項:1)確保考慮到優先級的布爾順序,但只要您正確處理括號,可能不會是一個問題,2)這聽起來像你不會實現短路,這可能是一件好事,3)如果你的興趣是清晰的代碼,這可能是好的;如果你有興趣提高速度(和能力),但你可能想看看Tokenization。使用一個非常小的潛在參數集,可以很簡單地使用一個令牌id數組。 – TASagent

回答

5

另一個選項是創建一個DataTable並使用Select方法。

// create data table 
var data = new DataTable(); 
data.Columns.Add("NAME.FULLNAME", typeof(bool)); 
data.Columns.Add("DOB.OPTIONAL", typeof(bool)); 
data.Columns.Add("ID", typeof(bool)); 
data.Columns.Add("DOB.REQUIRED", typeof(bool)); 
data.Columns.Add("COUNTRY", typeof(bool)); 

// fill data table 
data.Rows.Add(true, false, true, true, false); 

// see if it's a match 
var isMatch = data.Select("(NAME.FULLNAME AND DOB.OPTIONAL) OR (ID AND DOB.REQUIRED) OR (ID AND COUNTRY)").Any(); 
+0

真是個好主意 – Jonesopolis

1

只要你的括號嵌套總是像你的例子,你提出的解決方案聽起來很容易實現。但是,如果它們可以嵌套,那麼你正在談論製造一個狀態機,或者至少以某種方式實現匹配括號,這是不重要的。來處理

一種方法是給所有TRUE OR FALSETRUE,然後更換所有(TRUE)TRUE,這應該處理所有的情況下更換,但是這是一個很大的替代。儘管如此,使用字符串作爲您的方案中的狀態佔位符似乎沒問題,不過您可能會考慮一些小的性能增益,而不是使用字詞TRUEFALSE,並將某些編碼用於和和或,如01&和。