tags:

views:

242

answers:

5

Hi guys,

yes it's another .net regex question :) (please excuse the long waffle leading up to the actual question)

I'm allowing users to use simple date/time macros for entering dates quickly (they don't want a date picker)

for example they can enter:
d +1d -2h
this will give them a date time string of todays's date, plus one day, minus two hours.

anyways I've created a regex to match these which works fine (probably not the best way to do it but it works!):
\b[DTdt]( *[+-] *[1-9][0-9]* *[dDhHmMwW])*\b

as you've probably guessed i'm using the regex to validate these entries before parsing them to calculate the resulting datetime. At first I used something like:

Regex rgxDateTimeMacro = new Regex(@"\b[DTdt]( *[+-] *[1-9][0-9]* *[dDhHmMwW])*\b");

if(rgxDateTimeMacro.isMatch(strInput)){
  ...string passes...
}

I then quickly realised that isMatch returns true if there's any matches in the passed string,
d +1d +1
would return true ^__^

so i changed it around to do something like this:

Regex rgxDateTimeMacro = new Regex(@"\b[DTdt]( *[+-] *[1-9][0-9]* *[dDhHmMwW])*\b");
MatchCollection objMatches = rgxDateTimeMacro.Matches(strInput);

if (objMatches.Count > 0)
{
    // to pass.. we need a match which is the same length as the input string...
    foreach (Match m in objMatches)
    {
        if (m.Length == strInput.Length)
        {
            ...string passes...
        }
    }
}

now this works fine, but my question is this: is there a simpler way to check if a string (the whole string) matches a regex? I've had a google around, but cant seem to find an obvious answer.

hope this makes sense

Pete


UPDATE

thanks for all the quick answers, ^$ does the trick : )

(showing my inexperience with regexes ^__^)

+6  A: 

If I understand correctly, use: ^my regex$

^ - Start of the string
$ - End of the string

Kobi
+1: And I think you need to pass the "Multi-Line Mode" option.
John Gietzen
+1 Thats's the way
Rashmi Pandit
+1 Personally I use `^ $` in most of my regexes for this reason!
Stevo3000
A: 

Use this RegEx:

"^\b[DTdt]( *[+-] *[1-9][0-9]* *[dDhHmMwW])*\b$"

The ^ character matches the beginning of the string, while $ means end of the string.

Patonza
A: 

use: \Abla\Z

  1. \A Beginning of subject.
  2. \Z End of subject.

or use: ^bla$ with multiline mode on.

  1. ^ Beginning of a line.
  2. $ End of a line.
John Gietzen
+1  A: 

Write a better pattern that only matches what you really want to match! ;)

My suggestion;

^[DTdt](\s+[+-]\s+[1-9][0-9]*[dDhHmMwW])+$

Short explanation to show differences;

1: ^                  beginning of string
2: [DTdt]             matches 1 character of the given
3:  (                 open group 1
4:   \s+              one or more whitespaces
5:   [+-]             either + or -
6:   \s+              see above
7:   [1-9][0-9]*      matches one number of 9 followed by none or more numbers of 10
8:   [dDhHmMwW]       one of the characters
9:  )                 close group 1
10: +                 let group 1 only repeat 1 or more times
11: $                 end of string

I hope you see the differences to your pattern.

Matches: D +19d, t -99w +14d, T +75m -64H, D -1d +4m -44h

No Matches: d, d +1, T +1H -2, +1D -5M, -134d, t-4m, t +5d5, D -3m-5d+3g

ApoY2k
`[+|-]` is probably a mistake (should be '+|-' or `[+-]`). I also think the OP want's to match small numbers (that's even in the example: `d +1d -2h`)
Kobi
Where did I write `[+|-]`? Sorry, I just edited it ;-) - To only match small numbers, OP already has a wrong number-matching. Should be something like `[1-2][0-9]*`or `[1-9]+` depending on the numbers...
ApoY2k
A: 

In regular expressions, you can use the ^ and $ characters to indicate the expression should match the whole test string:

  • ^ as the very first character means "Match from the start of my test string".
  • $ as the very last character means "Match to the end of my test string".

Combined, (e.g. ^abc$) the entire test string must match the expression.

Programming Hero