regex multiplication problem

M

Mark_B

The following is working for me but I want to include numbers in scientific
notation.

public double Evaluate( string expr )
{
const string Num = @"(\-?\d+\.?\d*|\-?\.\d+)"
Regex reMulDiv = new Regex(Num + @"\s*([*/])\s*" + Num);

other stuff:

while ( reMulDiv.IsMatch( expr ) )
{
Regex restar = new Regex(@"\*");
string bstr = reMulDiv.Match(expr).Value.ToString();
bstr = restar.Replace(bstr, "\\*");
string a=reMulDiv.Match(expr).Groups.SyncRoot.ToString();
string astr = DoMulDiv(reMulDiv.Match(expr));
Regex rx = new Regex(bstr);
expr = rx.Replace(expr, astr);
}

other stuff
return (Convert.ToDouble(expr));
}

public string DoMulDiv( Match m )
{
int i = 0;

double n1 = Convert.ToDouble(m.Groups[1].Value);
double n2 = Convert.ToDouble(m.Groups[3].Value);

switch (m.Groups[2].Value.ToString())
{
case "/":
return ( n1 / n2 ).ToString();
case "*":
return ( n1 * n2 ).ToString();
default:
return "";
}
}

Trying to scale-up to include numbers in sci notation.


const string Num = @"((\-?\d+\.?\d*|\-?\.\d+)([E][-+]?[0-9]+)?)";

Trouble is n1, n2 ,n3 are nolonger the first#, the operator, and the last#.
The number of groups varies and the position of the numbers and operator is
not predictable. I think my problem is that I am not implementing the
function properly. But the rework (without a hack) is evading me.

please help
 
A

Arne Vajhøj

Mark_B said:
The following is working for me but I want to include numbers in scientific
notation.

public double Evaluate( string expr )
{
const string Num = @"(\-?\d+\.?\d*|\-?\.\d+)"
Regex reMulDiv = new Regex(Num + @"\s*([*/])\s*" + Num);

other stuff:

while ( reMulDiv.IsMatch( expr ) )
{
Regex restar = new Regex(@"\*");
string bstr = reMulDiv.Match(expr).Value.ToString();
bstr = restar.Replace(bstr, "\\*");
string a=reMulDiv.Match(expr).Groups.SyncRoot.ToString();
string astr = DoMulDiv(reMulDiv.Match(expr));
Regex rx = new Regex(bstr);
expr = rx.Replace(expr, astr);
}

other stuff
return (Convert.ToDouble(expr));
}

public string DoMulDiv( Match m )
{
int i = 0;

double n1 = Convert.ToDouble(m.Groups[1].Value);
double n2 = Convert.ToDouble(m.Groups[3].Value);

switch (m.Groups[2].Value.ToString())
{
case "/":
return ( n1 / n2 ).ToString();
case "*":
return ( n1 * n2 ).ToString();
default:
return "";
}
}

Trying to scale-up to include numbers in sci notation.


const string Num = @"((\-?\d+\.?\d*|\-?\.\d+)([E][-+]?[0-9]+)?)";

Trouble is n1, n2 ,n3 are nolonger the first#, the operator, and the last#.
The number of groups varies and the position of the numbers and operator is
not predictable. I think my problem is that I am not implementing the
function properly. But the rework (without a hack) is evading me.

I think you need something more powerful than regex.

What you are asking for is a standard feature in a lexical scanner
and parser.

Find a lexical scanner and parser generator for .NET, specify
a grammar for what you want and generate the code.

Arne
 
P

Pavel Minaev

Mark_B said:
The following is working for me but I want to include numbers in scientific
notation.

public double Evaluate( string expr )
{
const string Num = @"(\-?\d+\.?\d*|\-?\.\d+)"
Regex reMulDiv = new Regex(Num + @"\s*([*/])\s*" + Num);

other stuff:

while ( reMulDiv.IsMatch( expr ) )
{
Regex restar = new Regex(@"\*");
string bstr = reMulDiv.Match(expr).Value.ToString();
bstr = restar.Replace(bstr, "\\*");
string a=reMulDiv.Match(expr).Groups.SyncRoot.ToString();
string astr = DoMulDiv(reMulDiv.Match(expr));
Regex rx = new Regex(bstr);
expr = rx.Replace(expr, astr);
}

other stuff
return (Convert.ToDouble(expr));
}

public string DoMulDiv( Match m )
{
int i = 0;

double n1 = Convert.ToDouble(m.Groups[1].Value);
double n2 = Convert.ToDouble(m.Groups[3].Value);

switch (m.Groups[2].Value.ToString())
{
case "/":
return ( n1 / n2 ).ToString();
case "*":
return ( n1 * n2 ).ToString();
default:
return "";
}
}

Trying to scale-up to include numbers in sci notation.


const string Num = @"((\-?\d+\.?\d*|\-?\.\d+)([E][-+]?[0-9]+)?)";

Trouble is n1, n2 ,n3 are nolonger the first#, the operator, and the last#.
The number of groups varies and the position of the numbers and operator is
not predictable. I think my problem is that I am not implementing the
function properly. But the rework (without a hack) is evading me.

For one thing, you can always use named groups:

const string Num = @"\-?\d+\.?\d*|\-?\.\d+"
Regex reMulDiv = new Regex("(?<larg>" + Num + @")\s*(?<op>[*/])\s*(?
<rarg>" + Num + ")");
...
double n1 = Convert.ToDouble(m.Groups["larg"].Value);
double n2 = Convert.ToDouble(m.Groups["rarg"].Value);
switch (m.Groups["op"].Value.ToString())

However, I would also recommend you to use a proper parser generator
for this task, rather than trying to hack one on your own with regex.
Coco/R (http://www.ssw.uni-linz.ac.at/coco/) is LL(1) - which is quite
enough to parse arithmetic expressions - easy to use, has good
documentation and is rather lightweight; ANTLR (http://antlr.org) is
very powerful - LL(*) - but has a somewhat steeper learning curve, and
is slower; and there are plenty more if you look around.
 
M

Mark_B

Thank you Pavel

Pavel Minaev said:
Mark_B said:
The following is working for me but I want to include numbers in scientific
notation.

public double Evaluate( string expr )
{
const string Num = @"(\-?\d+\.?\d*|\-?\.\d+)"
Regex reMulDiv = new Regex(Num + @"\s*([*/])\s*" + Num);

other stuff:

while ( reMulDiv.IsMatch( expr ) )
{
Regex restar = new Regex(@"\*");
string bstr = reMulDiv.Match(expr).Value.ToString();
bstr = restar.Replace(bstr, "\\*");
string a=reMulDiv.Match(expr).Groups.SyncRoot.ToString();
string astr = DoMulDiv(reMulDiv.Match(expr));
Regex rx = new Regex(bstr);
expr = rx.Replace(expr, astr);
}

other stuff
return (Convert.ToDouble(expr));
}

public string DoMulDiv( Match m )
{
int i = 0;

double n1 = Convert.ToDouble(m.Groups[1].Value);
double n2 = Convert.ToDouble(m.Groups[3].Value);

switch (m.Groups[2].Value.ToString())
{
case "/":
return ( n1 / n2 ).ToString();
case "*":
return ( n1 * n2 ).ToString();
default:
return "";
}
}

Trying to scale-up to include numbers in sci notation.


const string Num = @"((\-?\d+\.?\d*|\-?\.\d+)([E][-+]?[0-9]+)?)";

Trouble is n1, n2 ,n3 are nolonger the first#, the operator, and the last#.
The number of groups varies and the position of the numbers and operator is
not predictable. I think my problem is that I am not implementing the
function properly. But the rework (without a hack) is evading me.

For one thing, you can always use named groups:

const string Num = @"\-?\d+\.?\d*|\-?\.\d+"
Regex reMulDiv = new Regex("(?<larg>" + Num + @")\s*(?<op>[*/])\s*(?
<rarg>" + Num + ")");
...
double n1 = Convert.ToDouble(m.Groups["larg"].Value);
double n2 = Convert.ToDouble(m.Groups["rarg"].Value);
switch (m.Groups["op"].Value.ToString())

However, I would also recommend you to use a proper parser generator
for this task, rather than trying to hack one on your own with regex.
Coco/R (http://www.ssw.uni-linz.ac.at/coco/) is LL(1) - which is quite
enough to parse arithmetic expressions - easy to use, has good
documentation and is rather lightweight; ANTLR (http://antlr.org) is
very powerful - LL(*) - but has a somewhat steeper learning curve, and
is slower; and there are plenty more if you look around.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top