0

I need to calculate VB expression from following strings:

"stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33"

"stringVar1=  \"stringVar1Value\" and boolVar1<>False or intVar1=22 and intVar2=33"

"stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33"

I need to parse it to array of variables of class

 public class ExpressionUnit
    {
        public string Variable { get; set; }
        public string Operator { get; set; }
        public string Value { get; set; }
    }

Where Variable is "stringVar1", Operator is "=" and Value is "stringVar1Value". Or array of strings with strictly order:

{ "stringVar1", "=", "stringVar1Value", "and", "boolVar1", "<>", "False", "or", "intVar1", "=", "22", "and", "intVar2", "=", "33" }

I will appritiate any suggestions or ideas.

Mr.B
  • 3,484
  • 2
  • 26
  • 40
  • string splitting, but possible spaces make mess. – Mr.B Dec 29 '16 at 13:38
  • 1
    This could be overkill, but maybe Roslyn can help: https://github.com/dotnet/roslyn/wiki/Getting-Started-VB-Syntax-Analysis – Peter B Dec 29 '16 at 13:41
  • Perhaps something like this? http://stackoverflow.com/questions/4629/how-can-i-evaluate-c-sharp-code-dynamically – Eric Burdo Dec 29 '16 at 13:44
  • I don't think so. I need to parse vb code that is given as string to an expression. – Mr.B Dec 29 '16 at 13:52
  • Two more ideas: https://benohead.com/three-options-to-dynamically-execute-csharp-code/ and http://stackoverflow.com/questions/5618218/executing-c-sharp-or-vb-net-code-at-runtime – Eric Burdo Dec 29 '16 at 14:05
  • Thank you for ideas but it seems to me like to fire a cannon at sparrows. I found a simpler solution. – Mr.B Dec 29 '16 at 14:41

2 Answers2

0

I found some solution:

 public static class StringParser
{
    public static List<string> ParseExpression(string expression)
    {
        //expression = System.Text.RegularExpressions.Regex.Replace(expression, @"\s+", " ");

        string word = string.Empty;
        int i = 0;
        List<string> list = new List<string>();
        while (i < expression.Length)
        {
            if (expression[i] == ' ')
            {
                if (!string.IsNullOrEmpty(word))
                {
                    list.Add(word);
                    word = string.Empty;
                }
                i++;
                continue;
            }
            if (expression[i] == '=')
            {
                if (!string.IsNullOrEmpty(word))
                {
                    list.Add(word);
                }
                word = new string(expression[i], 1);
                list.Add(word);
                word = string.Empty;
                i++;
                continue;
            }
            if (expression[i] == '<')
            {
                if (!string.IsNullOrEmpty(word))
                {
                    list.Add(word);
                }
                word = new string(expression[i], 1);
                i++;
                word += expression[i];
                list.Add(word);
                word = string.Empty;
                i++;
                continue;
            }

            word += expression[i];
            i++;
            if (!string.IsNullOrEmpty(word) && i == expression.Length)
            {
                list.Add(word);
            }
        }

        return list;
    }
}

Unit tests prove that it works:

 [TestFixture]
public class VbExpressionParserTests
{
    [Test]
    public void VbExpressionParserTests_ParseExpression_String_List1()
    {
        string[] correctResult = { "stringVar1", "=", "\"stringVar1Value\"", "and", "boolVar1", "<>", "False", "or", "intVar1", "=", "22", "and", "intVar2", "=", "33" };
        string[] res = StringParser.ParseExpression("stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33").ToArray();
        CollectionAssert.AreEqual(correctResult, res);
    }
    [Test]
    public void VbExpressionParserTests_ParseExpression_String_List2()
    {
        string[] correctResult = { "stringVar1", "=", "\"stringVar1Value\"", "and", "boolVar1", "<>", "False", "or", "intVar1", "=", "22", "and", "intVar2", "=", "33" };
        string[] res = StringParser.ParseExpression("stringVar1=  \"stringVar1Value\" and boolVar1<>False or intVar1=22 and intVar2=33").ToArray();
        CollectionAssert.AreEqual(correctResult, res);
    }
    [Test]
    public void VbExpressionParserTests_ParseExpression_String_List3()
    {
        string[] correctResult = { "stringVar1", "=", "\"stringVar1Value\"", "and", "boolVar1", "<>", "False", "or", "intVar1", "=", "22", "and", "intVar2", "=", "33" };
        string[] res = StringParser.ParseExpression("stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33").ToArray();
        CollectionAssert.AreEqual(correctResult, res);
    }

    [Test]
    public void VbExpressionParserTests_ParseExpression_String_IdealExpression()
    {
        string[] correctResult = { "stringVar1", "=", "\"stringVar1Value\"", "and", "boolVar1", "<>", "False", "or", "intVar1", "=", "22", "and", "intVar2", "=", "33" };
        string[] res = StringParser.ParseExpression("stringVar1=\"stringVar1Value\" and boolVar1<>False or intVar1=22 and intVar2=33").ToArray();
        CollectionAssert.AreEqual(correctResult, res);
    }
}

enter image description here

Mr.B
  • 3,484
  • 2
  • 26
  • 40
0
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace MrB
{
    class Program
    {
        static void Main()
        {
            string s1 = "stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33";
            string s2 = "stringVar1=  \"stringVar1Value\" and boolVar1<>False or intVar1=22 and intVar2=33";
            string s3 = "stringVar1  =   \"stringVar1Value\"    and boolVar1<>False or intVar1=22 and    intVar2=33";

            var rgx = new Regex("=");
            var replacement = " = ";

            string s1b = rgx.Replace(s1, replacement);
            string s2b = rgx.Replace(s2, replacement);
            string s3b = rgx.Replace(s3, replacement);

            rgx = new Regex(@"\s+");
            replacement = " ";

            string s1c = rgx.Replace(s1b, replacement);
            string s2c = rgx.Replace(s2b, replacement);
            string s3c = rgx.Replace(s3b, replacement);

            string[] s1List = s1c.Split(' ');
            string[] s2List = s2c.Split(' ');
            string[] s3List = s3c.Split(' ');

            Debugger.Break();
        }
    }
}
Duncan Carr
  • 250
  • 1
  • 5
  • i.e. 1) find all equals signs & replace with a space either side 2) replace all multiple spaces with a single space 3) split on spaces - with give 13 elements – Duncan Carr Dec 29 '16 at 15:14