Tahmid
Tahmid

Reputation: 355

Split formatted time range expression by first space and hyphen

I want to split this string to 3 array element.

$string = 'MW 01:00 PM - 02:30 PM';

Output:

array[0] = MW
array[1] = 01:00 PM
array[2] = 02:30 PM

Help me with the regex expression that will extract that string to an array.

^[a-zA-Z\d-_]+$

Upvotes: 3

Views: 161

Answers (4)

nice_dev
nice_dev

Reputation: 17805

<?php 

$str = "MW 01:00 PM - 02:30 PM";

$matches = [];

preg_match("/^([a-zA-Z]+)\s+(\d{1,2}:\d{1,2}\s+PM)\s+\-\s+(\d{1,2}:\d{1,2}\s+PM)$/",$str,$matches);

print_r($matches);

OUTPUT

Array
(
    [0] => MW 01:00 PM - 02:30 PM
    [1] => MW
    [2] => 01:00 PM
    [3] => 02:30 PM
)

Explanation:

  • We have to match the string from the start to the end. So, we use ^ and $ at the corners of our regex.
  • ([a-zA-Z]+)\s+ is used to match alphabetic characters along with 1 more extra spaces.
  • \d{1,2} is used to match 1 or 2 digits of time(like 1, 01, 11 etc)

Regex demo

Upvotes: 1

mickmackusa
mickmackusa

Reputation: 47894

While you can split on sequences of one or more spaces and/or hyphens which are followed by a digit, regex is not your only option here. This is a text extraction task, not a text validation task. Looks how concise sscanf() can be.

When you have a string with predictable format and no optional characters, often enough sscanf() can be helpful. %s (in scanf() and printf() functions) acts to match visible characters (not spaces). The % marks the start of a placeholder, the (optional) next digit specifies how many characters to match, then the character class / negated character class defines what characters will qualify as a match.

Code: (Demo)

$string = 'MW 01:00 PM - 02:30 PM';
var_export(
    sscanf($string, '%s %8[^-] - %8[^-]')
);

Output:

array (
  0 => 'MW',
  1 => '01:00 PM',
  2 => '02:30 PM',
)

As an extension of requirements, if it is desirable to isolate each variable component as a separate element in the output array, see the following implementation.

Code: (Demo)

var_export(
    sscanf($string, '%s %2s:%s %s - %2s:%s %s')
);

Output:

array (
  0 => 'MW',
  1 => '01',
  2 => '00',
  3 => 'PM',
  4 => '02',
  5 => '30',
  6 => 'PM',
)

--

To cast the hour and minute substrings as integers, use %d. (Demo)

var_export(
    sscanf($string, '%s %d:%d %s - %d:%d %s')
);

Upvotes: 0

bobble bubble
bobble bubble

Reputation: 18490

You can split at spaces and optional hyphen if there is a digit ahead by use of a lookahead.

$arr = preg_split('/ +-? *(?=\d)/', $str);

See demo at regex101.com

Upvotes: 4

AymDev
AymDev

Reputation: 7554

This works too (but is longer):

$str = "MW 01:00 PM - 02:30 PM";
preg_match('/([A-Z]{2}) ([0-9]{2}:[0-9]{2} [A-Z]{2}) - ([0-9]{2}:[0-9]{2} [A-Z]{2})/', $str, $match);

echo '<pre>' . print_r($match, true) . '</pre>';

Output:

Array
(
    [0] => MW 01:00 PM - 02:30 PM
    [1] => MW
    [2] => 01:00 PM
    [3] => 02:30 PM
)

Upvotes: 0

Related Questions