Regular expressions and preg_split() - php

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

Related

Find and Replace Multi-Row Phrases/text Within PHP Arrays without damaging the array

Lets say I have an array:
$myarray = (
[0] => 'Johnny likes to go to school',
[1] => 'but he only likes to go on Saturday',
[2] => 'because Saturdays are the best days',
[3] => 'unless you of course include Sundays',
[4] => 'which are also pretty good days too.',
[5] => 'Sometimes Johnny likes picking Strawberrys',
[6] => 'with his mother in the fields',
[7] => 'but sometimes he likes picking blueberries'
);
Keeping the structure of this array intact, I want to be able to replace phrases within it, even if they spill over to the next or previous string. Also I don't want punctuation or case to impact it.
Examples:
String to Find:
"Sundays which are also pretty good"
Replace with:
"Mondays which are also pretty great"
After replace:
$myarray = (
[0] => 'Johnny likes to go to school',
[1] => 'but he only likes to go on Saturday',
[2] => 'because Saturdays are the best days',
[3] => 'unless you of course include Mondays',
[4] => 'which are also pretty great days too.',
[5] => 'Sometimes Johnny likes picking Strawberrys',
[6] => 'with his mother in the fields',
[7] => 'but sometimes he likes picking blueberries'
);
Curious if there is an ideal way of doing this. My original thought was, I would turn the array into a string, strip out punctuation and spaces, count the characters and replace the phrase based on the character count. But, it is getting rather complex, but it is a complex problem
This is a job for regular expressions.
The method I used was to implode the array with some glue (i.e. '&'). Then I generated a regular expression by inserting a zero-or-one check for '&' in between each character in the find string.
I used the regular expression to replace occurrences of the string we were looking for with the replacement string. Then I exploded the string back into an array using the same delimiter as above ('&')
$myarray = [
0 => 'Johnny likes to go to school',
1 => 'but he only likes to go on Saturday',
2 => 'because Saturdays are the best days',
3 => 'unless you of course include Mondays',
4 => 'which are also pretty great days too.',
5 => 'Sometimes Johnny likes picking Strawberrys',
6 => 'with his mother in the fields',
7 => 'but sometimes he likes picking blueberries'
];
// preg_quote this because we're looking for the string, not for a pattern it might contain
$findstring = preg_quote("Sundays which are also pretty good");
// htmlentities this in case it contains a string of characters which happen to be an html entity
$replacestring = htmlentities("Mondays which are also pretty great");
// Combine array into one string
// We use htmlentitles to escape the ampersand, so we can use it as a sentence delimeter
$mystring = implode("&", array_map('htmlentities', $myarray));
// Turns $findString into:
// S\&?u\&?n\&?d\&?a\&?y\&?s\&? \&?w\&?h\&?i\&?c\&?h\&? \&?a\&?r\&?e\&?
// \&?a\&?l\&?s\&?o\&? \&?p\&?r\&?e\&?t\&?t\&?y\&? \&?g\&?o\&?o\&?d
$regexstring = implode("\&?", str_split($findstring));
// Johnny likes to go to school&but he only likes to go on Saturday&because Saturdays are the
// best days&unless you of course include Mondays&which are also pretty great days
// too.&Sometimes Johnny likes picking Strawberrys&with his mother in the fields&but sometimes
// he likes picking blueberries
$finalstring = preg_replace("/$regexstring/", $replacestring, $mystring);
// Break string back up into array, and return any html entities which might have existed
// at the beginning.
$replacedarray = array_map('html_entity_decode', explode("&", $finalstring));
var_dump($replacedarray);

PHP regular expression hours

I have this regular expression in php:
$programacion_array = preg_split("/(([0-9]{2}):([0-9]{2}))/",$html, -1, PREG_SPLIT_DELIM_CAPTURE);
I want to split a text by finding the hours of the programs, sample text:
asdf06:20Programold07:20Programnew
But my regular expression is returning me this:
[1] => 06:20 [2] => 06 [3] => 20 [4] => Programold
I don't see what I am missing.
Try getting rid of the inner match groups, e.g. use just:
/([0-9]{2}:[0-9]{2})/
This will work as shown here: http://ideone.com/u44OIt

regex to find year/month substring

Can someone help me with a regular expression to get the year and month from a text string?
Here is an example text string:
http://www.domain.com/files/images/2012/02/filename.jpg
I'd like the regex to return 2012/02.
This regex pattern would match what you need:
(?<=\/)\d{4}\/\d{2}(?=\/)
Depending on your situation and how much your strings vary - you might be able to dodge a bullet by simply using PHP's handy explode() function.
A simple demonstration - Dim the lights please...
$str = 'http://www.domain.com/files/images/2012/02/filename.jpg';
print_r( explode("/",$str) );
Returns :
Array
(
[0] => http:
[1] =>
[2] => www.domain.com
[3] => files
[4] => images
[5] => 2012 // Jack
[6] => 02 // Pot!
[7] => filename.jpg
)
The explode() function (docs here), splits a string according to a "delimiter" that you provide it. In this example I have use the / (slash) character.
So you see - you can just grab the values at 5th and 6th index to get the date values.

Regex skipping value

Greetings All
I am trying to get the values in the 4th column from the left for this url. I can get all the values but it skips the first one (e.g. 30 i think is the value on top right now )
My regex is
~<td align="center" class="row2">.*([\d,]+).*</td>~isU
NOTE: HTML PARSING IS NOT AN OPTION RIGHT NOW AS THIS IS PART OF A HUGE SYSTEM AND CANNOT
BE CHANGED
Thanking you
Imran
You could just use:
/([\d,]+)/
As the javascript function can be exploited as a "regex selection point"
If you want your regex to work you need to use non-greedy expression, i.e. change .* to .*?
Also your first align match attribute in the HTML is surrounded in '' quotation marks, not "" in the HTML, for some weird inconsistent reason. Try this:
|<td align=["\']center["\'] class="row2">.*?([\d,]+).*?</td>|is
Edit:
$a = file_get_contents('http://www.zajilnet.com/forum/index.php?showforum=31');
preg_match_all('|<td align=["\']center["\'] class="row2">.*?([\d,]+).*?</td>|is',$a,$m);
print_r($m[1]);
Result:
Array
(
[0] => 30
[1] => 16
[2] => 56
[3] => 14
[4] => 96
[5] => 4
[6] => 0
[7] => 17
[.... and more....]

Identify date-related text in a longer message

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

Categories