Customize regular expression of php - php

i have a string which is something like
<?php
$string = Monday & SUNDAY 11:30 PM et/pt;
//or
$string = Monday 11:30 PM et/pt;
?>
i want to fetch '11:30 PM' in both the cases for which i guess i cant use explode so what will be the regular expression for this ,,,also please tell me something pretty nice to learn regular expressions.
Thanks in advance

Credit goes to the commenters below for several fixes to the original approach, but there were still some unresolved issues.
If you want a fixed 2 hour format: (0[0-9]|1[0-2]):[0-5]\d [AP]M

to validly match a twelve-our-clock i'd use a regex like below. A twelve-hour-clock goes from 01:00 to 12:59:
$regex = "#\b(?:0[0-9]|1[0-2]):[0-5][0-9] [AP]M\b#i";

Malik, to retrieve time/date you might use premade library regexes, search this query: http://regexlib.com/Search.aspx?k=digit&c=5&m=-1&ps=20
Basically your time fields are similar, (having the same delimiter ':' ), i'd recommend simple regex: \d{1,2}:\d{2} [PA]M to match in the input string. If you want make it case-insensitive use i, pattern modifier.
For the basics of regex welcome to read here.
I give you this match function for PHP (i after second slash (/) makes pattern case-insensitive: am, AM, Am, aM will be equal):
preg_match('/\d{1,2}:\d{2} [PA]M/i', $string, $time);
print ($time);
If there might not be a space after digits (ex. 11:30am) or more then one space char., then the regex should look like this:
/\d{1,2}:\d{2}\s*[PA]M/i

this code will give you 11:30 PM
preg_match('$([0-9:]{3,5}) ([AP])M$','Monday & SUNDAY 11:30 PM et/pt',$m);
echo $m['1']." ".$m['2']."M";

Related

Are universal characters allowed in PHP explode()

I need to get everything before "On Sun, May 27, 2012 at 6:25 AM,"
I am hoping to get everything before "On xxx, xxx xx, xxxx at xx:xx xx,"
The problem here is that May, 27, and 6 are all variable in length. What is the best tool for this job. Due to my lack of experience with regex I am trying to use explode() but it doesn't appear it can do the job here. Is regex my best option?
[EDIT]
I ended up using a combination of answers. I went with:
preg_match("/(.*)On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i", $to, $end);
Something like this, I guess:
/On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i
[EDIT]
As per the comment: I have added support for case insensitive (by adding the i modifier to the end of the regex). I have also change the spaces in the expression to \s to allow any whitespace character, and added + to allow multiples spaces between words.
I haven't changed it to support long day names or short month names, as the questions specified that month name was variable in length but didn't specify day name as being variable. However, it should be trivial enough to add these variants if required.
[EDIT]
$to = "Let me know how this response looks..... On Sun, May 27, 2012 at 6:25 AM, Pr";
preg_match("/On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i", $to, $end);
This code works for the example given in your comment.
Hope that helps.
preg_match('/(.*?) On \w+, \w+ \d?\d, \d+ at \d?\d:\d?\d \w\w,/', 'grab this text here On Sun, May 27, 2012 at 6:25 AM,', $matches);
echo $matches[1];
// echoes 'grab this text here'
(.*?) matches everything in the beginning, \w+ matches any alphanumeric character 1 or more times, \d?\d matches either one or two digits
a regular expression would work since that's what it was made for: selecting data based on a pattern. You could however explode on ',' (comma) and just implode the first 4 elements together again to form your sentence. I doubt using regular expression will be faster in this case.
Ultimately it's your preference: which is better readable and understandable by you.
The main advantage regular expression would have in this particular case is hat they can extract specific values/patterns, so you could easily have them set aside the month for instance.
$dateString = "On Sun, May 27, 2012 at 6:25 AM, some other text here";
// using explode/implode
$result = explode(',',$dateString);
print "we got: " . implode(',', array_slice($result,0,3)) . "\n";
// using regular expression
$pattern = "/On [A-Z,a-z]{3}, [A-Z,a-z]{3} [0-9]+, [0-9]{4} at [0-9,:]+ (?:A|P)M/U";
preg_match($pattern,$dateString,$match);
print "We got: " . $match[0] . "\n";
Please also read the PHP manual, Regular Expressions subsection together with an initial tutorial
Personally in this case I think reg exp might be overkill both visually and performance wise. Do learn regular expressions though, they can be very helpful at times.

PHP regex sytax with preg_replace

PHP REGEX is a weakness of mine, but still I manage to get some things done with online tools. Consider the following:
A subject string which generally follows this pattern: 1551 UTC 04 June 2012
I want to extract the "04" and assign it to the $day variable using below:
$day = preg_replace("/^([0-9]{4})\s([A-Z]{3})\s([0-9]{2})\s([A-Za-z]{3,})\s([0-9]{4})$/", "$3", $weather['date']);
This works on the following website: http://sqa.fyicenter.com/Online_Test_Tools/Test_Regular_Expression_Search_Replace.php
but I can't get it to work in my script... $day would equal the whole subject string.
The result of your var_dump() is string(38) "1551 UTC 04 June 2012 ". It has 38 chars while it should be only 21. So it looks like there are multiple whitespaces in the string.
Try to trim() your input string and replace \s with \s+ to support multiple whitespaces:
$day = preg_replace("/^([0-9]{4})\s+([A-Z]{3})\s+([0-9]{2})\s+([A-Za-z]{3,})\s+([0-9]{4})$/", "$3", trim($weather['date']));
you say preg_replace, but I think you want to use preg_match(). Is that correct that you don't want to replace the "04" but you just want to put it into a the variable $day? If so use preg_match(). In your description you say you want to capture only the "04" part, but your regex has many capture groups (anything within "()" is a capture group and will be returned in the array you give to preg_match).

Preg_replace simple math problem with solution?

I have strings that contain simple math problems 1+10, 2+2, 5-3... I'm wanting to be able to match these math problems and replace them with the solution.
So that: Jimmy turns 5+5 on Friday. is changed to: Jimmy turns 10 on Friday.
I dont need multiplication or division at this point so i assume its relatively simple however im not classically trained in PHP. I assume i will need a REGEX to match the problem, but im pretty much lost from there.
1+10 becomes 11
2+2 becomes 4
Just "eval" the replacement - but take care, it's eval (Demo):
$subject = 'Jimmy turns 5+5 on Friday, Martha 1+10 on Saturday and Petra is 2*2 today.';
$pattern = '~(\d+[*/+-]\d+)~e';
# ^^^ e = eval modifier
# Jimmy turns 10 on Friday, Martha 11 on Saturday and Petra is 4 today.
echo preg_replace($pattern, '$1', $subject);

Extract date from string in format "DD MMM YYYY"

I am trying to extract a date from a string variable and was hoping to get some help.
$editdate = "Content last modified on 17 May 2011 at 23:13";
from this string, I am trying to extract 17 May 2011, please keep in mind that the date will vary and the code needs to be able to extract any date in this format, DD MMM YYYY.
I thought of using preg_match to do this but I couldn't come up with a proper regex pattern that would extract the date properly.
Is this possible to do with regex or should I use a different function?
Thanks for the help !
Try:
$timestamp = strtotime( str_replace( array("Content last modified ", "at"), "", $editdate ) );
Which will leave you with an epoch time stamp that you can then output however you like using date()
This is possible with a regex. Given the format DD MMM YYYY you would need a regex that matches two (or one?) digits, then one space, three letters, one space and four digits.
That would look like:
$regex = '/(\d{2} [a-z]{3} \d{4})/i';
This can be optimized further.
Presuming the textual content of your string is always the same, and that it always ends with the time...
$editdate = substr($editdate, 25, -9); // 17 May 2011
However, this is very inflexible if the date format were ever to change.
Try this 'un:
preg_match('/(\d?\d [A-Za-z]+ \d\d\d\d) at (\d\d\:\d\d)/', $editdate, $matches);
print_r($matches);
$date = $matches[1];
$time = $matches[2];
I THINK that'll work in all cases (though it is pretty ugly).... :)
This might be the pattern that does the trick:
([0-9]){1}([0-9]){0,1}(\s.*\s)([0-9]){4}
Search for 1 digit then there might be another, followed by a space and character, a space and 4 digits for the year.

PHP: Time validation RegEx?

I am using following regex to validate date in format dd/mm/yyyy in php:
preg_match("/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/", $e_startdate, $matches)
But what will be the regex to validate time in the format 10:20 PM or AM. I want a regex which will validate following format for me.
<number><number><colon><number><number><space><AM or PM>
Thanks
You can use the regex:
(0[0-9]|1[0-2]):[0-5][0-9] [AP]M
The following should validate the format you requested:
preg_match("/(\d{2}):(\d{2}) (AM|PM)/", $e_startdate, $matches);
Note that this is not necessarily a valid time. You could enter stuff like 32:62 AM. You need something like this for time validation:
preg_match("/(0?\d|1[0-2]):(0\d|[0-5]\d) (AM|PM)/i", $e_startdate, $matches);
Mind to match the whole thing case-insensitive (like i did in the second example). Otherwise lowercase am, pm, etc. are not going to work.
Regular Expression:
(([0-1][0-9])|([2][0-3])):([0-5][0-9]):([0-5][0-9])
Validates time in MySQL time format. 24 hour time colon separated hours:minutes:seconds hh:mm:ss
Matches: 09:30:00 | 17:45:20 | 23:59:59
Non-Matches: 24:00:00
/\d{2}:\d{2} (AM|PM)/
I started with elusive's answer, but needed a bit more flexibility. This one makes the minutes optional, as well as the space before AM/PM
/(0?\d|1[0-2])(:(0\d|[0-5]\d))?[ ]?(A|P)M/i

Categories