Preg_replace simple math problem with solution? - php

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);

Related

How to preg_replace same items in one subject php?

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.

Customize regular expression of 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";

Regular Expression to extract dynamic strings up to a certain point

my RegEx is written here and it does not work no matter how I change it, substitute characters what not. I have a list of strings that may have 3 words or 8 words. Is there a easier way to cut off the RegEx when we hit a certain character or string? Let me show you what I mean:
Here are some examples of strings I will deal with:
WKT8100 Cooperative Education Work Term Preparation 15 hrs/w
CST8259 Web Programming Languages II 5 hrs/w
CST8265 Web Security Basics 5 hrs/w
CST8267 Ecommerce 4 hrs/w
I want to extract only the course name and ID from the string and leave out the number of hours I need, so leaving me with:
WKT8100 Cooperative Education Work Term Preparation
as a return.
My RegEx currently is like this:
RegEx = "/[a-zA-Z]{3}[0-9]{4}[A-Z]{0,1}\s[a-zA-Z]{3,20}\s[a-zA-Z]{0,20}\s[a-zA-Z]{0,20}\s[a-zA-Z]{0,20}\s/";
I a RegEx that extracts the hours correctly so maybe if there is a method I can use with substr. That way I can basically extract everything before the hours RegEx and don't have to worry about a complex RegEx line.:
HoursRegEx = "#\s[0-9]{1,2}?\shrs\/w#i";
Why not:
/(.*) \d+ hrs\/w/
This should capture all characters before the x hrs/w part.
For a little more explanation, this just creates a capturing group that contains whatever it found before seeing: a space, one or more digits, another space, and then the sequence "hrs/w". Since you don't care what's before the end part, why try to recognize it?
If it always ends in " hrs/w", you can do this:
$string = "WKT8100 Cooperative Education Work Term Preparation 15 hrs/w";
$string = trim($string)
$lastSpace = strrpos($string, " ");
$string = trim(substr($string, 0, $lastSpace));
$lastSpace = strrpos($string, " ");
$hours = trim(substr($string, $lastSpace));
$nameID = trim(substr($string, 0, $lastSpace));
That's a way off the top of my head w/o using regex. I can't give you any regex without first doing some extensive refresher research.
p.s. Jordan's looks much cleaner.

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.

Searching for data within a string. Regular expressions?

I have some strings I need to scrape data from. I need a simple way of telling PHP to look in the string and delete data before and after the part I need. An example is:
When: Sat 19 Sep 2009 22:00 to Sun 20 Sep 2009 03:00&nbsp;
I want to delete the "When: " and then remove the & and everything after it. Is this a Regex thing? Not really used them before.
I would not use regular expressions for this.
$data = substr($input, 6, strpos($input, '&') - 6);
Yes, regex can do this kind of thing in its sleep.
$result = preg_replace('/When:(.*)&.*/', '$1', $text);
UPDATE
If you want to find the date range only, in the middle of a lot of other text, here is a crude regex that will match the one in the question...
if (preg_match('/[a-z]{3} [0-9]{2} [a-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2} to [a-z]{3} [0-9]{2} [a-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2}/i', $text, $regs)) {
$result = $regs[0];
} else {
$result = "";
}
So you would want to keep "Sat 19 Sep 2009 22:00 to Sun 20 Sep 2009 03:00"
Well you can go for a regexp alright. I don't know much about the Regexp in PHP, but in PERL, you could do somehing like
/^When: (.*)\ $/ .
The (.*) could then be used to get all that is what you want to keep. In PERL, that would be looking the $1 var.
Or you could do something like
/^When: (.)\&.$/ if the content after the & is variable.
Also, you must watch out. If the string you want to keep contains &, then it might a little more tricky.
But RegExp are usually the way to got for this type of work.

Categories