2017-03-07 54 views
0

我寫一個C#程序,請採用以下格式驗證令牌的數量表達

Name==Me && Age>18 || City== NewYork 

(由二進制運算AND和OR加盟條件)一些篩選表達有哪些呢

一個標記
{Name, ==, Me , &&, Age, >, 18, ||, City, ==, NewYork}. 

之後,過濾邏輯將創建一個過濾器。

問題:我想對標記器的標記數量進行一級驗證。但我無法弄清楚令牌的數量是多少。

if(!IsValidCount(tokens.Count)) return false; 

IsValidCount()裏面的邏輯是什麼?

這可能是比C#更多的數學,任何幫助表示讚賞

+0

'tokens.Count'返回什麼?我的理解應該是'11',不是嗎? – HimBromBeere

+0

是用例如所示的花括號書寫的標記器'字符串'嗎? – Nino

+0

過濾器中令牌的數量。對於名稱== Me &&年齡> 18 ||城市==紐約,11是計數 – Jimmy

回答

1

每個條件必須包含3個標記(2個字段+1個比較器)。 另外,對於每個附加條件,我們必須添加一個二元運算(AND/OR)來分隔它們(使它總共有4個令牌)。

其結果是,一個有效的標記生成器將包括以下令牌數量的:

3 + 4 + 4 + 4 ...

因此,你可以驗證的令牌的數量是有效的這個公式:

string tokenizer = "{Name, ==, Me , &&, Age, >, 18, ||, City, ==, NewYork}"; 
var tokens = tokenizer.Split(','); 
if (tokens.Length % 4 == 3) 
{ 
    //valid 
} 
else 
{ 
    //not valid 
} 

你可以得到更嚴格的檢查每4個令牌的確是一個二元運算,但這是你來決定。我希望我有幫助

+0

是的,僅供參考,BurnsBA在評論中實際上比你更快地回答了這個問題。 – Jimmy

+0

@Jimmy,我在寫我的答案,沒有刷新頁面,所以我沒有看到它 – Innat3

0

這是我對這個問題的。我猜這可能會寫得更乾淨,更容易理解,但是... :) 此外,它可能無法在所有情況下正確工作,但您應該明白。我還添加了一些例子。

好的,這裏是帶註釋的代碼。如果你有任何問題隨時問。

static void Main(string[] args) 
{ 
    string s = "{ Name, ==, Me, &&, Age, >, 18, ||, City, ==, NewYork }"; 
    bool ok1 = IsValidExpression(s); 
    s = "{ Name, ==, Me, &&, Age, >, 18 }"; 
    bool ok2 = IsValidExpression(s); 
    s = "{ Name, ==, ==, Me, &&, Age, >, 18 }"; 
    bool notok = IsValidExpression(s); 
    s = "{ Name, Me, &&, Age, >, 18 }"; 
    bool notok2 = IsValidExpression(s); 
    s = "{ Name, ==, Me, &&, Age, > ||, City, ==, NewYork }"; 
    bool notok3 = IsValidExpression(s); 
    Console.ReadLine(); 

} 

static bool IsValidExpression(string stringToValidate) 
{ 
    List<string> tokens = stringToValidate.Replace("{", "").Replace("}", "").Split(',').Select(t => t = t.Trim()).ToList(); 

    List<string> operators = new List<string>() { "==", "!=", "<", ">" }; 
    List<string> boolOps = new List<string>() { "&&", "||" }; 
    //split by and/or 
    var boolOpsIndexes = tokens.Where(t => boolOps.Contains(t)).Select(t => tokens.IndexOf(t)).ToList(); 
    //check for AND/OR positions 
    if (boolOpsIndexes.Any(b => b == 0) || boolOpsIndexes.Any(b => b == tokens.Count - 1)) //bool op is at first or last position 
     return false; 

    //make "virtual one at the end, so the program enters loop one or more times 
    boolOpsIndexes.Add(tokens.Count - 1); 

    int lastOpIndex = 0; 
    //iterate through all indexes where and/or were found 
    foreach (var boolOpIndex in boolOpsIndexes) 
    { 
     //take expressions from last AND/OR to next one 
     var tokensPart = tokens.Skip(lastOpIndex).Take(boolOpIndex).ToList(); 

     if (tokensPart.Count != 3) //there is not 3 parts there... not ok 
      return false; 

     //if there is more or less than one comparison operator 
     if (tokensPart.Count(t => operators.Contains(t)) != 1) 
      return false; //not ok 

     //check for both sides of operators 
     int opIndex = tokensPart.Where(t => operators.Contains(t)).Select(t => tokensPart.IndexOf(t)).First(); 
     //check for operators positions 
     if (opIndex == 0 || opIndex == tokensPart.Count - 1) //operator is at first or last position 
      return false; //not ok 

     //check if left and right side od operator contains something and not operator 
     if (tokensPart[opIndex - 1] != string.Empty && !operators.Contains(tokensPart[opIndex - 1]) 
      && 
      tokensPart[opIndex + 1] != string.Empty && !operators.Contains(tokensPart[opIndex + 1])) 
      continue; 

     lastOpIndex = boolOpIndex + 1; 
    } 

    return true; 

} 
+0

我的問題是你如何驗證計數? – Jimmy

+0

你不清楚你想要檢查什麼?我寫的這個例子會告訴你有三個操作符。你還想要什麼?你想測試每個操作員是否有兩個值進行比較,並且他們在操作員的左側和右側? – Nino

+0

也是可能的運營商? '{「==」,「!=」,「<", ">」}'?還要別的嗎?關於布爾運算符 - 有沒有'&&','||'或'^'...? – Nino

0

我認爲MathParser-org-mXparser可以輕鬆幫助 - 您可以計算表達式,但也可以使用表達式標記。

Expression e = new Expression("Name==Me && Age>18 || City== NewYork"); 
mXparser.consolePrintTokens(e.getCopyOfInitialTokens()); 

結果:

[mXparser-v.4.0.0] -------------------- 
[mXparser-v.4.0.0] | Expression tokens: | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] | TokenIdx |  Token |  KeyW |  TokenId | TokenTypeId | TokenLevel | TokenValue | LooksLike | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] |   0 |  Name |    |   -1 |   -1 |   0 |   NaN | argument | 
[mXparser-v.4.0.0] |   1 |   == |   == |   1 |   3 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   2 |   Me |    |   -1 |   -1 |   0 |   NaN | argument | 
[mXparser-v.4.0.0] |   3 |   && |   && |   1 |   2 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   4 |   Age |    |   -1 |   -1 |   0 |   NaN | argument | 
[mXparser-v.4.0.0] |   5 |   > |   > |   4 |   3 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   6 |   18 |  _num_ |   1 |   0 |   0 |   18 |    | 
[mXparser-v.4.0.0] |   7 |   || |   || |   3 |   2 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   8 |  City |    |   -1 |   -1 |   0 |   NaN | argument | 
[mXparser-v.4.0.0] |   9 |   == |   == |   1 |   3 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   10 |  NewYork |    |   -1 |   -1 |   0 |   NaN | argument | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 

請按照mXparser tutorial

Regards