tags:

views:

81

answers:

3

Hi All

I need help in regular expressions, match and replace pattens. I am working on rates.
my rates can be like

345.00
456
2345.90
341.34

I have to check if the rate ends in 9, if not i have to end the rate with 9 and a $ symbol.

The rates after running the rule should become

$349.00
$459.00
$2349.00
$339.00

I am storing the rate as string so that it would be easy when I use the Regex.IsMatch function.

can someone give me the regular expression for the matchpattern and replace pattern.

I am struggling with this from half a day and need help.

Thanks Sujatha

A: 

I'd use multiple Regexp patterns, since this doesn't seem like it has to work on a lot of input:

First, lets get rid of the float:

s/\..*$//

Then, let's handle the '9':

s/.$/9/

Finally, add the '$' and the '.00':

s/^/$/
s/$/.00/
polemon
There surely is a "better" solution, as in smaller, but you'd have to use backtracking and saved matches, which usually scale less good on the NFA that most Regex-engines umplement.
polemon
thank you for all your answers
Sujatha
+1  A: 

An easier and more intuitive way is to use integer arithmetic:

// convert amount to int, then:
amount = amount - (amount % 10) + 9
// or more succintly
amount += 9 - (amount % 10)

And that will give you what you want. You can then use String.Format() to get the currency formatting:

public static String ToMoney(string amount) 
{
    int x = Convert.ToInt32(double.Parse(amount));
    x += 9 - (x%10);
    return String.Format("{0:C}", x);
}

See it in action on ideone

NullUserException
+1  A: 
string[] ss = { "345.00", "456", "2345.90", "341.56" };

foreach (string s in ss)
{
  Console.WriteLine(Regex.Replace(s, @"^(\d*)\d(?:\.\d+)?$",
                                     @"$$${1}9.00"));
}

output:

$349.00
$459.00
$2349.00
$349.00

Initially, (\d*) matches as many digits as it can and stores them in capturing group #1 (for example, it matches 341 in 341.56). Then it backs off one position to let \d match the final digit (group #1 now contains just 34). Finally, (?:\.\d+)? matches the fraction if there is one (.56 in this case).

In the substitution, $$ inserts a dollar sign ($ has a special meaning in substitutions, so you have to escape it with another $). ${1} inserts the contents of capturing group #1 (34 in the case of 341.56). Normally you can use just $1, but this time the group reference is followed by another digit in the substitution, so it would look like I was referring to group #19. The braces around the 1 tell it unambiguously I want group #1 followed by 9. Finally, .00 completes the substitution.

That regex you came up uses named capture groups, so you use ${price1} instead of ${1} to insert the first part of the number. The other two capturing groups aren't needed. In fact, there's a lot of stuff in there that doesn't really belong. And I see you're removing the fractional part now instead of replacing it with .00.

One more thing: you don't need to call IsMatch() before starting a replacement; that's taken care of by the Replace() method.

Alan Moore
+1 for this explanation... great!
opatut