mferg
mferg

Reputation: 49

Regex- First instance of Time in a string

I am trying to build a regular expression that would pull the first time out of a string.

The issue is the time format is not standardized.

Here are the possible variations.

':' with 1 hour digit before the ':' (ex. 9:00 pm)
':' with 2 hour digits before the ':' (ex. 10:00pm)
no minutes with with 1 hour digit (ex 9pm)
no minutes with with 1 hour digit (ex 10pm)

Additionally there may or may not be a space before "am" or "pm"

Here is an example string.

7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text

I would like this string to return "7:30 pm"

Upvotes: 0

Views: 60

Answers (4)

Giuseppe Ricupero
Giuseppe Ricupero

Reputation: 6272

You did not specify the tool you want to use, here a simple implementation using sed:

echo '7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text' | sed 's/\([0-2]\?[0-9]\(:[0-5][0-9]\)\? *[ap]m\).*/\1/i'

Legenda:

'[0-2]\?[0-9]'       match the hour (with 1 or 2 digits)
'\(:[0-5][0-9]\)\?'  match the minutes (optional)
' *'                 optional spaces
'[ap]m'              match am,pm,AM,PM (also Am,aM,pM,Pm)*
'.*'                 match all the rest of the string

In addiction: the external \(...\) create a group of all the above elements (a backreference) used later in the substitution part of the regex \1. *: The last /i modifier make the regex case insensitive

You can rewrite all as a standard perl regex:

/(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/

Little ruby code:

#!/usr/bin/env ruby

input = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text"
puts input[/(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/]

Upvotes: 2

user4227915
user4227915

Reputation:

Try this regex:

(?i)\d{1,2}(?::\d{2})?\s*[ap]m

Explaining:

(?i)            # insensitive case
\d{1,2}         # one or two digits
(?:             # optional group
    :\d{2}      # the minutes
)?              # end optional group
\s*             # any spaces
[ap]m           # "am" or "pm"

Regex live here.

Hope it helps.

Upvotes: 2

Andre Pastore
Andre Pastore

Reputation: 2897

A almost generic solution may be achieved using following expression:

([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM))

It considers capturing groups, getting all present time strings on string.

In javascript, it might be tested like following:

var testTime = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text";

var timeRex = /([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM))/g;

var firstTime = timeRex.exec(testTime)[0];

console.log(firstTime);

I really believe that there is a better general solution. I will try some more stable, then publish it here.

Upvotes: 1

Mayur Koshti
Mayur Koshti

Reputation: 1852

You can use the following regex:

\d{1,2}\:?(?:\d{1,2}|)\s*[ap]m

Upvotes: 1

Related Questions