How to search and remove various string in array elements? - php

I have array with login data, where I need to remove various, user defined strings, for example, my array looks like:
Array ( [0] => Date: 16/03/2015 20:39 [1] => IP Address: 93.136.99.89 [2]
What I want to do is remove "Date:" from first array element and "IP Address" from second array element.
Now I am using str_replace:
$lastlogindate = str_replace('Date:', 'Datum:', $lastlogin[0]);
But is there more elegant way of do this, and maybe, find defined occurance, and then wrapp it with tag, for every defined occurance in string in array element?

You can also still use str_replace(), but pass array arguments to it:
$lastlogindate = str_replace(array('Date: ', 'IP Address: '), '', $lastlogin);
For input array:
$lastlogin = ['Date: 16/03/2015 20:39', 'IP Address: 93.136.99.89'];
It returns you:
Array ( [0] => 16/03/2015 20:39 [1] => 93.136.99.89 )

You can also use regex to replace like this
preg_replace("/(.*?: )(.*)/", "$2", $input); by iterating over your array and replacing each value.
$input = array( 0 => 'Date: 16/03/2015 20:39', 1 => 'IP Address: 93.136.99.89' );
$array_output = array();
foreach ($input as $key => $value){
array_push($array_output, preg_replace("/(.*?: )(.*)/", "$2", $value));
}
var_dump($array_output);
// this is the output
array(2) {
[0]=>
string(16) "16/03/2015 20:39"
[1]=>
string(12) "93.136.99.89"
}
Hope this helps

Related

PHP from string to multiple arrays at the hand of placeholders

Good day,
I have an I think rather odd question and I also do not really know how to ask this question.
I want to create a string variable that looks like this:
[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]
This should be processed and look like:
$variable = array(
'car' => array(
'Ford',
'Dodge',
'Chevrolet',
'Corvette'
),
'motorcycle' => array(
'Yamaha',
'Ducati',
'Gilera',
'Kawasaki'
)
);
Does anyone know how to do this?
And what is it called what I am trying to do?
I want to explode the string into the two arrays. If it is a sub array
or two individual arrays. I do not care. I can always combine the
latter if I wish so.
But from the above mentioned string to two arrays. That is what I
want.
Solution by Dlporter98
<?php
///######## GET THE STRING FILE OR DIRECT INPUT
// $str = file_get_contents('file.txt');
$str = '[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]';
$str = explode(PHP_EOL, $str);
$finalArray = [];
foreach($str as $item){
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]][] = $matches[2];
}
print_r($finalArray);
?>
This gives me the following array:
Array
(
[car] => Array
(
[0] => Ford
[1] => Dodge
[2] => Chevrolet
[3] => Corvette
)
[motorcycle] => Array
(
[0] => Yamaha
[1] => Ducati
[2] => Gilera
[3] => Kawasaki
)
)
The small change I had to make was:
Change
$finalArray[$matches[1]] = $matches[2]
To:
$finalArray[$matches[1]][] = $matches[2];
Thanks a million!!
There are many ways to convert the information in this string to an associative array.
split the string on the new line into an array using the explode function:
$str = "[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]";
$items = explode(PHP_EOL, $str);
At this point each delimited item is now an array entry.
Array
(
[0] => [car]Ford[/car]
[1] => [car]Dodge[/car]
[2] => [car]Chevrolet[/car]
[3] => [car]Corvette[/car]
[4] => [motorcycle]Yamaha[/motorcycle]
[5] => [motorcycle]Ducati[/motorcycle]
[6] => [motorcycle]Gilera[/motorcycle]
[7] => [motorcycle]Kawasaki[/motorcycle]
)
Next, loop over the array and pull out the appropriate pieces needed to build the final associative array using the preg_match function with a regular expression:
$finalArray = [];
foreach($items as $item)
{
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]] = $matches[2]
}
The following is an example of what will be found in the matches array for a given iteration of the foreach loop.
Array
(
[0] => [motorcycle]Gilera[
[1] => motorcycle
[2] => Gilera
)
Please note that I use the PHP_EOL constant to explode the initial string. This may not work if the string was pulled from a different operating system than the one you are running this code on. You may need to replace this with the actual end of line characters that is being used by the string.
Why don't you create two separate arrays?
$cars = array("Ford", "Dodge", "Chevrolet", "Corvette");
$motorcycle = array("Yamaha", "Ducati", "Gilera", "Kawasaki");
You could also use an Associative array to do this.
$variable = array("Ford"=>"car", "Yamaha"=>"motorbike");

Remove elements from an array that do not match a regex

In PHP, is there a function or anything else that will remove all elements in an array that do not match a regex.
My regex is this: preg_match('/^[a-z0-9\-]+$/i', $str)
My array's come in like this, from a form (they're tags actually)
Original array from form. Note: evil tags
$arr = array (
"french-cuisine",
"french-fries",
"snack-food",
"evil*tag!!",
"fast-food",
"more~evil*tags"
);
Cleaned array. Note, no evil tags
Array (
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[3] => fast-food
)
I currently do like this, but is there a better way? Without the loop maybe?
foreach($arr as $key => $value) {
if(!preg_match('/^[a-z0-9\-]+$/i', $value)) {
unset($arr[$key]);
}
}
print_r($arr);
You could use preg_grep() to filter the array entries that match the regular expression.
$cleaned = preg_grep('/^[a-z0-9-]+$/i', $arr);
print_r($cleaned);
Output
Array
(
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[4] => fast-food
)
I would not necessarily say it's any better per se, but using regexp and array_filter could look something like this:
$data = array_filter($arr , function ($item){
return preg_match('/^[a-z0-9\-]+$/i', $item);
});
Where we're returning the result of the preg_match which is either true/false. In this case, it should correctly remove the matched evil tags.
Here's your eval.in

Explode a POST variable after a pattern REGEX

I'm terrible at regex, hard to understand for me so I need some help. I have a variable which looks something like this:
["data:image/png;base64,Ivksfk...=", "data:image/png;base64,JksdkJkf...=", "data:image/png;base64,okKJjfeiw...="]
Those are 3 values which I want to split into an array. The way I see it, I want to split it at the comma which comes after a quote ", ". Can someone please help me with the regex for preg_split?
You could try the below code to split the input string according to ", "
<?php
$yourstring = '["data:image/png;base64,Ivksfk...=", "data:image/png;base64,JksdkJkf...=", "data:image/png;base64,okKJjfeiw...="]';
$regex = '~", "~';
$splits = preg_split($regex, $yourstring);
print_r($splits);
?>
Output:
Array
(
[0] => ["data:image/png;base64,Ivksfk...=
[1] => data:image/png;base64,JksdkJkf...=
[2] => data:image/png;base64,okKJjfeiw...="]
)
If you don't want "[,]" in the output then you could try the below code.
<?php
$data = '["data:image/png;base64,Ivksfk...=", "data:image/png;base64,JksdkJkf...=", "data:image/png;base64,okKJjfeiw...="]';
$regex = '~(?<=\["|", ")[^"]*~';
preg_match_all($regex, $data, $matches);
print_r($matches);
?>
Output:
Array
(
[0] => Array
(
[0] => data:image/png;base64,Ivksfk...=
[1] => data:image/png;base64,JksdkJkf...=
[2] => data:image/png;base64,okKJjfeiw...=
)
)
$string = '["data:image/png;base64,Ivksfk...=", "data:image/png;base64,JksdkJkf...=", "data:image/png;base64,okKJjfeiw...="]';
$parts = preg_split('/,\s/', $string);
var_dump($parts);
Program output:
array(3) {
[0]=>
string(34) ""data:image/png;base64,Ivksfk...=""
[1]=>
string(36) ""data:image/png;base64,JksdkJkf...=""
[2]=>
string(37) ""data:image/png;base64,okKJjfeiw...=""
}
So long as the double-quote symbol cannot occur within the double-quotes that contain the content, this pattern should validate and capture the three values:
^\["([^"]+)"\], \["([^"]+)"\], \["([^"]+)"\]$
If double-quotes can appear within the content, or the number of values is variable, then this pattern will not work.

How to sort/filter values from Array PHP?

I need to foreach values of this array:
My CODE:
<?php
print_r(array_filter($matches));
?>
Result of this CODE:
Array (
[0] => Array (
[0] => Age: // Name
[1] => 22 Yrs. // Value
[2] => Ethnicity: // Name
[3] => Caucasian // Value
[4] => Location: // Name
[5] => London, United Kingdom // Value
Now I want to get this values separated/filtered like:
$location = 'London, United Kingdom';
$age = '22 Yrs.';
So I can simply do a echo $age;
Remark: In some cases the user have NOT set all the values. So its not guaranteed that Value Age always exists in this array. Therefore I need something like:
If "Age:" is found in array then $age =
How can I do this? I have totally 33 names and 33 values in this array and need to filter them all based on IF statement to be sure that the value is the right value.
Result of var_dump($matches); :
array(1) {
[0]=> array(66) {
[0]=> string(202) " Age: "
[1]=> string(157) " 22 Yrs. "
[2]=> string(196) " Ethnicity: "
[3]=> string(146) " Caucasian "
[4]=> string(195) " Location: "
[5]=> string(175) " London, United Kingdom "
Result of var_export($matches); :
array (
0 => array (
0 => ' Age: ',
1 => ' 22 Yrs. ',
2 => ' Ethnicity: ',
3 => ' Caucasian ',
4 => ' Location: ',
5 => ' London, United Kingdom ',
Im newbie so if you have a better ways to do this then please advice.
Thank you for your kind help.
As noted in the comments above, I would try to modify the $matches if at all possible - it would be far easier to work with associative arrays for this use case.
However, taking it on face value that you're stuck with that data structure, here's one probably very naive approach...
this assumes that your data will always come out in the format [key, value, key, value, ...]:
<?php
// original data
$matches = array(
array(
'Age:',
'22 Yrs.',
'Ethnicity:',
'Caucasian',
'Location:',
'London, United Kingdom',
'Location:',
)
);
// chunk $matches sub-array into pairs
// we want each chunk to contain two elements,
// the first will be the key and the second will be the value
$chunks = array_chunk($matches[0], 2);
// apply a callback to each array element
$pairs = array_map(function($pair) {
// some basic error checking...
// if the matches subarray count is uneven for some reason
if (count($pair) !== 2) {
return array();
}
// assign each element in the pair
list($key, $val) = $pair;
// some basic key normalisation
// remove non alpha chars and lowercase
$key = strtolower($key);
$key = preg_replace('/\W+/', '', $key);
// return a key value pair
return array($key => $val);
}, $chunks);
// iterate over the pairs
// and extract into the current scope...
foreach ($pairs as $pair) {
extract($pair);
}
// and you should now be able to echo your values
echo $age;
echo $ethnicity;
echo $location;
Result:
22 Yrs.
Caucasian
London, United Kingdom
Hope this helps :) To reiterate, I would really recommend restructuring the original data structure because the above solution is hardly optimal.
This answer assumes you're working with the array that directly contains the data, unlike your output example that shows 3 nested arrays.
for($i=0; $i<(count($matches)/2); $i++){
$label = substr($matches[$i*2],0,-1);
$output[$label] = $matches[$i*2+1];
}
This will make $output an associative array, addressable like this:
echo($output["Age"]);
Unfortunately, it's impossible as far as I know to make it into individual variables.
Could be more easy try to use separately arrays, eg.
$Age = Array (
[0] => 22,
[1] => 33
);
$Ethnicity = Array (
[0] => "Caucasian",
[1] => "Other"
);
$Location= Array (
[0] => "London, United Kingdom",
[1] => "Germany"
);

Regex to get repeating matches within a match

I have this sample string in a source:
#include_plugin:PluginName param1=value1 param2=value2#
What I want is to find all occurances of #include_plugin:*# from a source with a result of the PluginName and each paramN=valueN.
At this moment I'm fiddling with something like this (and have tried many variants): /#include_plugin:(.*\b){1}(.*\=.*){0,}#/ (using this resource). Unfortunately I can't seem to define a pattern which is giving me the result I want. Any suggestions?
Update with example:
Say I have this string in a .tpl-file. #include_plugin:BestSellers limit=5 fromCategory=123#
I want it to return an array with:
0 => BestSellers,
1 => limit=5 fromCategory=123
Or even better (if possible):
0 => BestSellers,
1 => limit=5,
2 => fromCategory=123
You can do it in 2 steps. First capture the line with a regex, then explode the parameters into an array:
$subject = '#include_plugin:PluginName param1=value1 param2=value2#';
$pattern = '/#include_plugin:([a-z]+)( .*)?#/i';
preg_match($pattern, $subject, $matches);
$pluginName = $matches[1];
$pluginParams = isset($matches[2])?explode(' ', trim($matches[2])):array();
You can use this regex:
/#include_plugin:([a-zA-Z0-9]+)(.*?)#/
The PluginName is in the first capturing group, and the parameters are in the second capturing group. Note that the parameters, if any, has a leading spaces.
It is not possible to write a regex to extract to your even better case, unless the maximum number of parameters in known.
You can do extra processing by first trimming leading and trailing spaces, then split along /\s+/.
I'm not sure of your character-set that your PluginName can contain, or the parameters/values, but in case they are limited you can use the following regex:
/#include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)#/
This will capture the plugin name followed by any list of alpha-numeric parameters with their values. The output can be seen with:
<?
$str = '#include_plugin:PluginName param1=value1 param2=value2#
#include_plugin:BestSellers limit=5 fromCategory=123#';
$regex = '/#include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)#/';
$matches = array();
preg_match_all($regex, $str, $matches);
print_r($matches);
?>
This will output:
Array
(
[0] => Array
(
[0] => #include_plugin:PluginName param1=value1 param2=value2#
[1] => #include_plugin:BestSellers limit=5 fromCategory=123#
)
[1] => Array
(
[0] => PluginName param1=value1 param2=value2
[1] => BestSellers limit=5 fromCategory=123
)
)
To get the array in the format you need, you can iterate through the results with:
$plugins = array();
foreach ($matches[1] as $match) {
$plugins[] = explode(' ', $match);
}
And now you'll have the following in $plugins:
Array
(
[0] => Array
(
[0] => PluginName
[1] => param1=value1
[2] => param2=value2
)
[1] => Array
(
[0] => BestSellers
[1] => limit=5
[2] => fromCategory=123
)
)
$string = "#include_plugin:PluginName1 param1=value1 param2=value2# #include_plugin:PluginName2#";
preg_match_all('/#include_plugin:([a-zA-Z0-9]+)\s?([^#]+)?/', $string, $matches);
var_dump($matches);
is this what you are looking for?
array(3) {
[0]=>
array(2) {
[0]=>
string(55) "#include_plugin:PluginName1 param1=value1 param2=value2"
[1]=>
string(27) "#include_plugin:PluginName2"
}
[1]=>
array(2) {
[0]=>
string(11) "PluginName1"
[1]=>
string(11) "PluginName2"
}
[2]=>
array(2) {
[0]=>
string(27) "param1=value1 param2=value2"
[1]=>
string(0) ""
}
}
This Regex will give you multiple groups, one for each plugin.
((?<=#include_plugin:)(.+))

Categories