tags:

views:

49

answers:

1

I am trying to match on this string "$0.05/$0.10" and came up with this regular expression but I keep getting the error newline expression in constant, where have I gone wrong? Obviously the string can change and be with or without the decimal place so this would be valid also $25/$50 or or $1/$2.

My attempt:

@"\(\$(\d+\.\d{2})\+\$(\d+\.\d{2})\));

But obviously it doesn't work!

+4  A: 

Some things wrong with your original expression:

  • You weren't including the slash
  • The + between the two groups was odd
  • You weren't making the . optional
  • The . was matching any character instead of just .
  • Nothing was making the ".\d{2}" optional
  • It would find the match anywhere in the string (possibly correct for your use case; I've forced it to match the whole string)
  • The brackets were mismatched
  • You didn't need to put the whole thing in a capturing group; you can always match the whole pattern using group 0

Here's the fixed version:

@"^\$(\d+(?:\.\d{2})?)/\$(\d+(?:\.\d{2})?)$"

Short but complete example:

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main()
    {
        Match("$25/$2.05");
        Match("$2.05/$2.05");
        Match("$25.00/$22.05");
        Match("$25/$10");
        Match("x/$10");
        Match("$10/x");
        Match("$10$20");
    }

    private static readonly Regex Pattern = new Regex
        (@"^\$(\d+(?:\.\d{2})?)/\$(\d+(?:\.\d{2})?)$");

    static void Match(string text)
    {
        Match match = Pattern.Match(text);
        if (!match.Success) {
            Console.WriteLine("{0}: Match failed", text);
            return;
        }
        Console.WriteLine("{0}: Matched! First: {1} Second: {2}",
                          text, match.Groups[1], match.Groups[2]);
    }
}

Output:

$25/$2.05: Matched! First: 25 Second: 2.05
$2.05/$2.05: Matched! First: 2.05 Second: 2.05
$25.00/$22.05: Matched! First: 25.00 Second: 22.05
$25/$10: Matched! First: 25 Second: 10
x/$10: Match failed
$10/x: Match failed
$10$20: Match failed
Jon Skeet
@Kobi: Yup, was fixing that. @NullUserException: Yup, I removed that too.
Jon Skeet
Jon, thank you, and thanks for the explanation of where I was going wrong the "+" was odd because I actually copied the wrong regex up which was annoying but it was late and I was exasperated by then. One question: how do I modify it because I want to match on the whole string so $25/$2.05 would be the first match rather than returning two matches? Thanks.
flavour404
@flavour404: Just use `match.Groups[0]`. That's always "the complete match".
Jon Skeet