views:

97

answers:

4

I need an simple way to check whether a string that is sent to my function is of the form:

(x + n)(x + m) 
//the +'s can be minus'
//n and m represent a double
//x represents the char 'x'

Is there a simple string format that I can use to check that this is the form. As opposed to checking each character singularly.

The whitespace will be removed to save any confusion.

Regards

Lloyd

+2  A: 

You can use regular expressions to check this.

Andrew Bezzub
+4  A: 

Here's a stab at a RegEx example...

var pattern = @"^(\(x[+-]\d+(\.\d+)?\)){2}$";
var input = "(x-0.123)(x+5)";
var result = System.Text.RegularExpressions.Regex.IsMatch(input, pattern);

if (result) { 
  Console.Write("YAY IT MATCHES");
}
jessegavin
Thank you. I just can't seem to get my head around regex! Appreciated.
ThePower
Regex is super confusing. I use http://regexpal.com/ to play around with them until something works. They have a handy quick reference on the page.
jessegavin
Regular expressions are one of the more powerful items in your developer toolbox, but they can be a pain to learn using a compiled language. They really clicked for me in python because I could do things from the python interpreter and quickly try things out.
marr75
+1  A: 

!Regex

Use this and you won't have 2 problems ;)

 class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(IsGood1("+x(3)-)x-5+"));
            Console.WriteLine(IsGood1("(x * n)(x + m)"));
            Console.WriteLine(IsGood1(" ( x + 12.9) (x+33.9)"));
        }

        private static bool IsOrdered(string s) // bad idea
        {
            var ind = new List<int>();
            ind.Add(s.IndexOf('('));
            ind.Add(s.IndexOfAny(new char[] { '+', '-' }));
            ind.Add(s.IndexOf(')'));
            ind.Add(s.LastIndexOf('('));
            ind.Add(s.LastIndexOfAny(new char[] { '+', '-' }));
            ind.Add(s.LastIndexOf(')'));

            bool order = true;

            for (int i = 0; i < ind.Count - 1; i++)
            {
                order = order && (ind[i] < ind[i + 1]);
            }
            return order;
        }

        public static bool IsGood1(string s)
        {
            if (!IsOrdered(s)) return false;

            double m = 0;
            int c = 0;

            foreach (var item in s.Split(new char[] { '+', '-', '(', ')' }))
            {
                var xx = item.Trim();

                if (xx != "")
                    switch (c)
                    {
                        case 0:
                        case 2:
                            if (xx == "x") c++;
                            break;
                        case 1:
                        case 3:
                            if (double.TryParse(xx, out m)) c++;
                            break;
                    }
            }

            return c == 4;
        }

    }
TheMachineCharmer
won't that accept `+x(3)-)x-5+` , and all other combination of `[-+()]`?
Kobi
+1 Kobi Thanks! Took care of it but it looks dirty now! you know of some better way? Feel free to edit my answer :)
TheMachineCharmer
+1  A: 

This is a case where I think Regular Expressions make a lot of sense. Unlike C++, C# does not have a way (that I know of) to use string formatting as part of parsing a string.

Quoting Eric Lippert:

Is this clever? No. Beautiful? No. Short? No. Correct according to the specification?

I hope so, but I have not fully tested it. It looks pretty good though.

    static bool testJoin(string x)
    {
        string[] s = x.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (s.Length != 3) return false;
        if (s[1] != "+" && s[1] != "-") return false;
        if (s[0] != "x") return false;
        double tmp;
        return Double.TryParse(s[2], out tmp);
    }
    static bool testString(string x)
    {
        if (x.Length < 2) return false;
        if (x[0] != '(' || x[x.Length-1]!=')') return false;
        string[] y = x.Substring(1,x.Length-2).Split(new string[] { ")(" }, StringSplitOptions.None);
        if (y.Length != 2) return false;
        return testJoin(y[0]) && testJoin(y[1]);
    }
Brian
Note that our specifications might not agree. For example, I require there to be one or more spaces before and after the +/-.
Brian
For those who didn't get it, my reference to Eric Lippert was a joke, since his context was, "let's do it right, even if it isn't pretty" and my context is, "this isn't pretty."
Brian