I'm having problems on how to preg_match this time statement.
TF 02:30 pm-04:00 am
I was able to separate the time into the array but I also want to get the AM and PM as well as the letter T and F.
This is for a class schedule module that I am working on. The data I got from the database is that string. I want to separate them so that I can manipulate the entries for the calendar that I have.
Here's what I have at this point.
$sampleString = 'T 02:30 pm-04:00 am';
$pattern = '/([0-1]?\d|2[0-9]):([0-5]?\d)/';
preg_match_all($pattern,$sampleString,$time);
print_r($time);
The output:
Array (
[0] => Array (
[0] => 02:30
[1] => 04:00 )
[1] => Array (
[0] => 02
[1] => 04 )
[2] => Array (
[0] => 30
[1] => 00 )
)
Thanks.
As recommended by IMSoP, splitting this up into parts makes it easier (looking again, I think your hour regex could use improvement, as it will accept hours from 0-29, I've changed it to 0?[1-9]|1[0-2] instead, to accept only 1 - 12)
Days: [MTWHFS]+
Space: \s
Hour: 0?[1-9]|1[0-2]
Colon: :
Minute: [0-5]?\d
Space: \s
am/pm: [ap]m
hyphen: -
Hour: 0?[1-9]|1[0-2]
Colon: :
Minute: [0-5]?\d
Space: \s
am/pm: [ap]m
Then just put them together, surrounding the desired capturing groups with parentheses:
([MTWHFS]+)\s(0?[1-9]|1[0-2]):([0-5]?\d)\s([pa]m)-(0?[1-9]|1[0-2]):([0-5]?\d)\s([pa]m)
Related
000001 0001 000000000000001975 00 02 0 000 2017/12/13 14:13:27
i m developing a system with laravel.
this is the string i get from a csv file. i need to select this date and time. into an array. if i can select word that contain : (14:13:27) i can get time and same method to date.
Try this pattern:
/(\d{4}\/[^ ]+) \K([\d:]+)/
Online Demo
A simple solution would be -
$string= "000001 0001 000000000000001975 00 02 0 000 2017/12/13 44:13:27";
preg_match("/([0-9]+):([0-5][0-9]):([0-5][0-9])/", $string, $matches);
echo $matches[0];
I'm still unclear about the OP's exact desired output, but I was more-so underwhelmed by the patterns in the other answers. I'll post this battery of solutions for the betterment of Stackoverflow since I couldn't find a suitable duplicate to close with.
I'm using the tildes ~ as pattern delimiters so that the / characters in the pattern don't need to be escaped. Also, notice I am not calling \K to restart the fullstring match because there is no reason to do so.
Code: (Demo)
$string='000001 0001 000000000000001975 00 02 0 000 2017/12/13 14:13:27';
var_export(preg_match('~\d{4}/\d{2}/\d{2}~',$string,$out)?$out:[]); // date
echo "\n\n";
var_export(preg_match('~\d{2}:\d{2}:\d{2}~',$string,$out)?$out:[]); // time
echo "\n\n";
var_export(preg_match('~\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}~',$string,$out)?$out:[]); // full datetime
echo "\n\n";
var_export(preg_match('~(\d{4}/\d{2}/\d{2}) (\d{2}:\d{2}:\d{2})~',$string,$out)?$out:[]); // capture date and time
echo "\n\n";
var_export(preg_match_all('~\d{4}/\d{2}/\d{2}|\d{2}:\d{2}:\d{2}~',$string,$out)?$out:[]); // capture date or time
echo "\n\n";
var_export(preg_match('~(\d{4})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2})~',$string,$out)?$out:[]); // capture date digits and time digits
Output:
// date
array (
0 => '2017/12/13',
)
// time
array (
0 => '14:13:27',
)
full date time
array (
0 => '2017/12/13 14:13:27',
)
// capture date and time
array (
0 => '2017/12/13 14:13:27',
1 => '2017/12/13',
2 => '14:13:27',
)
// capture date or time
array (
0 =>
array (
0 => '2017/12/13',
1 => '14:13:27',
),
)
// capture date digits and time digits
array (
0 => '2017/12/13 14:13:27',
1 => '2017',
2 => '12',
3 => '13',
4 => '14',
5 => '13',
6 => '27',
)
p.s. For future readers, if you require stronger date validation than this, then regex is probably not the right tool for your task.
I need some direction on how to alter my current RegEx line.
Example string:
9:00 AM - 9:30 AM
Desired output:
900 930 (each can be an index in an array or whatever)..
Current approach:
preg_match('/^([0-9]{1,2}):([0-9]{1,2}) ?([ap]m)/i', trim($presentationtime), $matches);
however this only seems to get me the FIRST (stripped/parsed) time.
results:
$presentationtime = $matches[1] . $matches[2];
echo 'Matches check: '. $matches[0] . '<br>';
echo 'Matches check: '. $matches[1] . '<br>';
returns:
Matches check: 9
Matches check: 00
How can I alter my regex to get BOTH times (stripped/parsed the same way)..
I'm expecting a 6 index array..but can only get a 3 index/count array
as #anubhava says use preg_match_all
$presentationtime = '9:00 AM - 9:30 AM';
preg_match_all('/([0-9]{1,2}):([0-9]{1,2}) /', trim($presentationtime), $matches);
print_r($matches);
results:
Array
(
[0] => Array
(
[0] => 9:00
[1] => 9:30
)
[1] => Array
(
[0] => 9
[1] => 9
)
[2] => Array
(
[0] => 00
[1] => 30
)
)
Edit to answer the comment:
very lazy workaround to get one dimensional array, banal regex
$presentationtime = '9:00 AM - 9:30 PM';
preg_match('/([0-9]{1,2}):([0-9]{1,2})\s([apm]+)\s-\s([0-9]{1,2}):([0-9]{1,2})\s([apm]+)/i', trim($presentationtime), $matches);
result
Array
(
[0] => 9:00 AM - 9:30 PM
[1] => 9
[2] => 00
[3] => AM
[4] => 9
[5] => 30
[6] => PM
)
You have to simply use preg_match_all (as stated by anubhava in the comment) and remove the ^ at the start of the regex:
preg_match_all('/([0-9]{1,2}):([0-9]{1,2}) ?([ap]m)/i', trim($presentationtime), $matches);
Then $matches will be like:
Array
(
[0] => Array
(
[0] => 9:00 AM
[1] => 9:30 AM
)
[1] => Array
(
[0] => 9
[1] => 9
)
[2] => Array
(
[0] => 00
[1] => 30
)
[3] => Array
(
[0] => AM
[1] => AM
)
)
If you want to refine the regex you may use:
preg_match('/([0-9]{1,2}):([0-5]\d)\s*([ap]m)/i', trim($presentationtime), $matches);
The minute section is will match 2 digits from 00 to 59, the space section \s* is optional and matches more than one whitespace char (space, tab, CR, FF...)
One way of doing that:
$data = '9:00 AM - 9:30 AM';
print str_replace('-', ' ', preg_replace("/[^0-9-]/","", $data));
Result:
900 930
keep digits and dash
replace dash with space
In the previous example, I was using limited regex with preg_replace. To keep things simple and using time with AM/PM, I'd just explode (as you already thought about),
$data = '9:00 AM - 9:30 PM';
$timeArray = array_map('trim', explode('-', $data)); // trim each array item
$timeArray = array_map('Time24Hr', $timeArray); // clean up time
print_r($timeArray);
function Time24Hr($time) {
$time_ampm = explode(' ', $time);
if (strtolower(trim($time_ampm[1])) === 'am') {
// A
return $time_ampm[0];
// B
//return str_replace(':', '', $time_ampm[0]);
// C
//return $time;
}
$hr_min = explode(':', trim($time_ampm[0]));
// A
return ($hr_min[0] + 12) . ':' . $hr_min[1];
// B
//return ($hr_min[0] + 12) . $hr_min[1];
// C
//return ($hr_min[0] + 12) . ':' . $hr_min[1]. ' ' . $time_ampm[1];
}
Results:
Result A:
Array
(
[0] => 9:00
[1] => 21:30
)
Result B:
Array
(
[0] => 900
[1] => 2130
)
Result C: -- obviously this is insane, but you can easily make it sane. This is just an example
Array
(
[0] => 9:00 AM
[1] => 21:30 PM
)
Of course, this simplistic method can be streamlined much further. This method doesn't need regex.
I have looked at several of the other regular expressions questions here and on other message boards. I am beating my head against the wall because I just can't seem to wrap my head around this. (or regular expressions in general)
I am pulling a time stamp from a MYSQL database. This is automatically generated, so it is formatted normally: 2011-12-17 21:30:56
I want to break this up into an array without having to use multiple explodes. I am assuming preg_split() is the answer here. If you have a better idea, I am all ears (though I feel like I need to figure out how to use regular expressions at some point anyway.)
In any case, I am trying to split this up at each "-" ":" and " ". After a bit of reading it seems like a character class is the answer, here is my code, that is simply not working:
$date_arr = preg_split("/ [- :] /", $order['order_date']);
This is outputting: Array ( [0] => 2011-12-17 21:30:56 )
Where am I going wrong?
The reason your preg_split fails is because of the spaces surrounding [- :].
As it's currently written in will only split on " - ", " " and " : ".
$date_arr = preg_split("/ [- :] /", ... ); // original
$date_arr = preg_split("/[- :]/", ...); // fixed
Instead of using functions such as explode and preg_split to split your string, use strtotime and getdate:
print_r (
getdate (strtotime ("2011-12-17 21:30:56"))
);
...
Array
(
[seconds] => 56
[minutes] => 30
[hours] => 21
[mday] => 17
[wday] => 6
[mon] => 12
[year] => 2011
[yday] => 350
[weekday] => Saturday
[month] => December
[0] => 1324153856
)
You have unncesary spaces in regex. Try this:
preg_split("/[- :]/", '2011-12-17 21:30:56');
I'm currently writing a script that would extract all the dates from a message and convert them to timestamps. PHP's strtotime (similar to Unix's date -c 'some date') would be perfect for this, as it recognizes all kinds of dates, such as:
5pm today
2010-11-15 16:30
Thursday 8:00
However, I'm having trouble finding those dates in the first place. For example, in the following string,
I'll be there for dinner tomorrow at 9:00pm
I need to isolate "tomorrow at 9:00pm", as that's the part that strtotime recognizes.
Is there a regular expression or something similar that would return me all dates that can be parsed by strtotime?
The only thing I can think of is date_parse. A regular expression that matches any format accepted by strtotime would be huge.
An example of date_parse:
$str = "I'll be there for dinner tomorrow at 9:00pm";
$parsed = date_parse($str);
print_r($parsed);
It would output something like this (I removed the unimportant parts from it to make it the result lighter):
Array
(
[year] =>
[month] =>
[day] =>
[hour] => 21 // 9:00pm
[minute] => 0 // 9:00pm
[second] => 0 // 9:00pm
[fraction] => 0
[warning_count] => 1
[is_localtime] => 1
[zone_type] => 2
[zone] => -540
[is_dst] =>
[tz_abbr] => I
[relative] => Array
(
[year] => 0
[month] => 0
[day] => 1 // tomorrow (would be -1 for yesterday, etc.)
[hour] => 0
[minute] => 0
[second] => 0
)
)
Whether this works for you depends primarily on what your input looks like. If you have more than one instance of a date in your input string, it will not work as expected.
This might not be totally efficient, but should work for any date string that consists of up to 5 words in length. I would write the function, but I think you'll get the idea with the comments below...
$words = explode(' ',$original_string);
// Use the array_chunk() function break up this array into 1-word,
// 2-word, 3-word, and 4-word long substrings of the original string
// Reform them back into strings and pass each one through strtodate()
What is the best way to parse time from a string?
Example string: "this is 10:45 this is 10:48, 10:49, 10:50, 22:15";
Expected return:
[0] = 10:45
[1] = 10:48
[2] = 10:49
[3] = 10:50
[4] = 22:15
Thanks for any replies!!
This will give the output you want and limits your hour/minute numbers to valid values for the first position of the hour and the first position of the minute:
$y = "this is 10:45 this is 10:48, 10:49, 10:50, 22:15";
preg_match_all("/(([0-1]\d|2[0-3]):[0-5]\d)/",$y,$matches);
print_r($matches[1]);
/*
Outputs:
Array ( [0] => 10:45 [1] => 10:48 [2] => 10:49 [3] => 10:50 [4] => 22:15 )
/*
preg_match_all('/\d{2}:\d{2}/', $string, $matches);
You will have all your matches in $matches array.
That looks like a pretty simple case. try preg_match_all with "/\d\d:\d\d/"