src091
src091

Reputation: 2847

match two patterns followed one by another

I'm creating a calendar where users can set events and time in single line, for example:

"6pm supper" - event with start time only

"8:00 - 16:00 work" - event with time period

Regex I'm currently using to get times:

[\d]{1,2}[.|:]?[\d]{0,2}[\s]?[am|pm|AM|PM]{0,2}

It works fine but I can't figure out how to filter out the unwanted occurrences of time if they happen, for example:

"6pm supper at '8pm' restaurant" In this example '8pm' is a restaurant name but it will be interpreted as event with time period while it's not. I suppose I have to write a regex that will only match time pattern in the beginning of line and the next pattern that follows after it without any words between but I have no success composing such a regex so far.

Any suggestions?

Upvotes: 0

Views: 797

Answers (3)

Would ^[\d]{1,2}[.|:]?[\d]{0,2}[\s]?[am|pm|AM|PM]{0,2} fix the problem of matching the '8pm' in your example?

The ^ is used to match the start of a line. $ can be used for matching the end of a line (in case you need that for later;) ).

UPDATE:

This one's a bit ugly but it seems to work:

[^'"][\d]{1,2}[.|:]?[\d]{0,2}[\s]?[am|pm|AM|PM]{0,2}[^'"]|^[\d]{1,2}[.|:]?[\d]{0,2}[\s]?[am|pm|AM|PM]{0,2}

The first option ensures that if a time appears in the middle of a string, it can't be surrounded by any kind of quote character. The second option allows for times that are at the start of a string. This is ugly looking and can probably be improved somewhat... but it seems to work for me.

UPDATE:

I think this version's a little easier to read:

([^'"]|^)[\d]{1,2}[.|:]?[\d]{0,2}[\s]?[am|pm|AM|PM]{0,2}[^'"]

Upvotes: 0

Nalum
Nalum

Reputation: 4213

What if you used the following regex

([\d]{1,2}[.|:]?[\d]{0,2}[\s]?[apm|APM]{0,2})( - )?([\d]{1,2}[.|:]?[\d]{0,2}[\s]?[apm|APM]{0,2})?(.*)

This would allow you to access the different sections e.g. 6pm supper at '8pm' restaurant would be:

(6pm)()()( supper at '8pm' restaurant)
 $1  $2$3 $4

Upvotes: 1

Jens
Jens

Reputation: 25593

You could try using a lookbehind construct, to only select dates that are not preceded by letters other than "a","p", and "m". Something in the line of

(?<![letters other than apm].*)

According to http://www.regular-expressions.info/lookaround.html, not all Regex implementations support this in the needed extent, though. Most do not seem to allow .* in a lookbehind.

Upvotes: 0

Related Questions