I have a question regarding one case.
I'm using php preg_replace() function to format data from this string:
12:05 Place1 12:40 14:00 16:30 Place2 "Test" 29 Janury
I need it to be outputed like this:
<li>29 January - Place1 - 12:05</li>
<li>29 January - Place2 "Test" - 12:40 14:00 16:30</li>
My regular expression:
/(\d[0-9]:\d[0-9]).+?(\D+).+?(\d[0-9]\s(January|February|March))/
I'm currently using something like this:
$text = "12:05 Place1 12:40 14:00 16:30 Place2 "Test" 29 Janury";
$data = preg_replace("/(\d[0-9]:\d[0-9]).+?(\D+).+?(\d[0-9]\s(January|February|March))/", "<li>$3 - $2 - $1</li>", $text);
echo $data;
The problem it shows only first matches,
29 January - Place1 - 12:05
Maybe someone know how to solve this case?
Thanks :)
It is not possible to do in one regex because you want to use a match from the end of the string before the PCRE engine has reached it. You need to do this in two steps:
preg_match() with PREG_OFFSET_CAPTURE to capture the date from the end of the string into another variable. Use the offset it provides to truncate the original string.
preg_match_all() the truncated string to get the times & places as an array, then iterate the array to use each match & the date variable to create the list. '/((?:\s*+\d\d:\d\d)++)\s++((?:.(?!\d\d:\d\d\s))++)\s*+/' is a suitable pattern.
Related
How can I validate the date input from users following the format mm/yyyy and also the yyyy range is from 2002 until 2030. So the month should be between 1 to 12 and all of the years below 2002 and 2030 in invalid. Here is my current regular expression:
^(0[1-9]|1[012])[- /.](20)\d\d$
Since you're forced to use regex, here you are:
^(0[1-9]|1[012])[- /.](20(?:0[2-9]|[12]\d|30))$
It works similar to the month validation pattern you wrote - 0[2-9] matches 2002 to 2009, [12]\d matches 2010 to 2029, and 30 matches 2030.
You can Validate a Gregorian date using the checkdate() function; however this requires you to be in a DateTime/Date format, it's useful for making sure people don't do stuff like: 35/02/2014
However, something like this could work?
([0-2][0-9]|31)\/(0[1-9]|1[0-2])\/(200[2-9]|20[1-2][0-9]|2030)
And then cast the string to a DateTime object and run the checkdate() function upon it to check it's gregorian?
^(0[1-9]|(1[0-2]+)+)\/(20(0[2-9]|([1-2][0-9])|30))$
You can use this pattern. You can test it here also. http://regexr.com/3a60s
Breakdown:
^(
0[1-9]|(1[0-2]+)+)
\/
(20(0[2-9]|([1-2][0-9])|30)
)$
Explanation:
Matches between 01 to 09, or 10 to 12.
Matches your "/"
Matches 3 year sets starting with 20.
2002 to 2009 with 0[2-9]
or 2010 to 2029 with [1-2][0-9]
or 2030, which is matched with the literal 30
You may check by pattern.. this way
<input type="text" pattern="^(0[1-9]|1[012])[- /.](20(?:0[2-9]|[12]\d|30))$" />
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";
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).
how can i replace date/time in this format 'Fri Mar 23 15:21:08 2012' with preg_replace?
Date in this format is present couple of times in my text and i need to replace it with current time/date.
Thanks,
Chris
Well, what you need is an expression that will match 3 letters (Fri) followed by a space and another three letters (Mar).
First we need to match some letters:
/[a-z]/
We can match exactly 3 letters like this:
/[a-z]{3}/
...and we'll need it to be case insensitive:
/[a-z]{3}/i
...so the first part is just:
/[a-z]{3} [a-z]{3}/i
Next, we need to match either 1 or 2 numerics. A numeric can be represented with the escape sequence \d, so we'd use:
/\d{1,2}/
Next we match the time string, using the same escape sequence:
/\d{2}:\d{2}:\d{2}/
...followed by a final 4 digit year:
/\d{4}/
Put it all together and we get:
/[a-z]{3} [a-z]{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}/i
// Fri Mar 23 15 : 21 : 08 2012
Now, we need to replace it with the current date and time. The usual place we'd go for that is the date() function, but how to we get that into the replacement dynamically? Well we could pass it as a string literal, or we could use a callback function to get it from preg_replace_callback(). But, preg_replace() gives us the e modifier which causes the replacement string to be evaluated for PHP code. We have to be careful and sparing with it's use, as with any PHP eval(), but this is a legitimate use case.
So our final PHP code looks like this:
preg_replace(
'/[a-z]{3} [a-z]{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}/ie',
"date('D M j H:i:s Y')",
$str
);
See it working
I think listing the finite sets of options is kind of better for these task and it will also save you from false positives. These are the patterns to match each part of the date format:
Days: (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)
Months: (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
Day: \d{1,2}
Time: \d{1,2}:\d{2}:\d{2}
Year: \d{4}
Putting everything together:
(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d{1,2}:\d{2}:\d{2} \d{4}
The code might look like:
$current_date = date('D M j H:i:s Y');
$text = preg_replace(
'/(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d{1,2}:\d{2}:\d{2} \d{4}/i',
$current_date,
$text
);
See a working example.
preg_replace('/Fri Mar 23 15:21:08 2012/',date('D M d H:i:s Y'),$string);
Normally do what you want.
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);