views:

242

answers:

4

I need to create a Regular Expression (in Javascript) that will match a specific sentence structure. In my case, it's "Course ### day ###", where ### can be any 1 to 3 digit number. Additionally, it can be "week" instead of "day", so "Course ### week ###" is also valid.

So far, I've come up with:

var regTest=/^(Course) \d{1,3} (day)|(week) \d{1,3}$/

The problem is that this expression matches "Course 9 day 1", which is what I want, but it would also match "Course 9 day 1 scheduled on 07/01/09".

In other words, the following returns a value of 0:

"Course 9 day 1".search(regTest)

But this one also returns 0:

"Course 9 day 1 scheduled on 07/01/09".search(regTest)

I want the first test to return 0, but I want the second one to return -1. I need the expression to ONLY match up until the ### following day/week. How do you make it to stop at that point?

A: 

An additional level of grouping is needed:

var regTest=/^(Course) \d{1,3} ((day)|(week)) \d{1,3}$/
pmf
+3  A: 

You need to move the OR (the pipe) into the parenthesis between the day and week:

/^(Course) \d{1,3} (day|week) \d{1,3}$/

If the pipe is inside the parens then it matches "day" or "week" in that position. With the pipe not inside of a parens it matches either the first half of the expression (i.e. "Course ### day") or the last half of the expression (i.e. "week ###").

Also, if you are just trying to validate that the string matches the pattern you can use "test" rather than "search":

if(/^(Course) \d{1,3} (day|week) \d{1,3}$/.test(someString)) {
    // it matches!
}
Prestaul
Thanks for the catch!
A: 

You want

var regTest=/^(Course) \d{1,3} (day|week) \d{1,3}$/

(Notice that (day)|(week) has changed to (day|week)). Your old regex was actually two, joined with the |. You see, | is one of the less (least?) tightly binding regex metacharacters, which means that ab|cd will match "ab" and "cd", but not "abd" or "acd".

Sean Nyman
A: 

You have everything right except that you need to put the check for (day)|(week) in a parenthesis block, i.e.

var regTest=/^(Course) \d{1,3} ((day)|(week)) \d{1,3}$/

You can actually reduce the statement to

var regTest=/^Course \d{1,3} (day|week) \d{1,3}$/

BTW, I do know why you don't need the parenthesis around Course. I'm not sure why you don't need them around day and week. If I had access to sed right know I would like to see how it treated ((day)|(week)) versus (day|week).

Mike