substitutions string php module 2 - php

I have an array with several elements like this:
cars = array ("name" => "volkswagen", "description" => "hier by hidd by hisd by hidf by"
"name" => "fiat", "description" => "hier by hias by hisad by hiasd by");
how could replace elements in each array in each two occurrences description by half. That is the result:
carsModified = array ("name" => "volkswagen", "description" => "hier by hidd replace hisd by hidf replace"
"name" => "fiat", "description" => "hier by hias replace hisad by hiasd replace");
by substitutions for replace.

If I understood correctly, you have an array of the following format:
$arr = array (
array(
"name" => "volkswagen",
"description" => "hier by hidd by hisd by hidf by"
),
array(
"name" => "fiat",
"description" => "hier by hias by hisad by hiasd by"
)
);
Now, you want to modify the description field (or any other), which contains the word "by" with the word "replace". You want to replace only the even occurrences. For this, we will write a function that accepts a string and replaces every second occurrence of a string. There are many ways to do it, this is one:
function replace_evens($search, $replace, $subject){
$parsed = explode($search, $subject);
$doubles = array();
for ($i=0, $n=count($parsed); $i<$n-1; $i+=2){
$doubles[] = $parsed[$i] . $search .$parsed[$i+1];
}
if ($i==$n-1) $doubles[] = $parsed[$n-1];
return implode($replace, $doubles);
}
Now we will iterate over the array, and foreach element (which is also an array) we will go over all of it's fields. Notice the reference (&) before $a because we want to modify the same element and not clone it. Also notice that we append spaces around the value $v
foreach($arr as &$a){
foreach($a as $k=>$v){
$a[$k] = trim(replace_evens(' by ', ' replace ' , ' ' . $v. ' ' ));
}
}
print_r($arr);
Hope it helps. Take in mind that I did not test this code...

Related

PHP - pregmatch array from json_encode for str_replace() and return it to array as well

I have this array:
$form = array(
array(
"type" => "text",
"value" => "
Hello #name
How old are you? #age
How are you today? #condition"
),
array(
"type" => "font",
"family" => "Arial",
"size" => 6,
"weight" => "Bold"
)
);
Then I did this json_encode($form) and It has this output:
[
{
"type":"text",
"value":"\r\n Hello #name\r\n\r\n How old are you? #age\r\n \r\n How are you today? #condition"
},
{
"type":"font",
"family":"Arial",
"size":6,
"weight":"Bold"
}
]
The thing is json_encode() also acts like a string so I can also do like this:
$old = array('#name','#age',#condition');
This $old data is what I will put in the str_replace();
But I want to do it in an array form like get all data with # symbol.
Can we do that with pregmatch? or is there any other way to do it?
Yes, You can get list of words that start with # by using preg_match
I would use a function like this to help me get data from any type of input :
/**
* We will take two param on this function
* $input is the data we will be look into
* $tags is reference to a array, we will store out result in this array.
*/
function fetch_tags($input, &$tags){
if(is_array($input)){
// If input is array, iterate it and pass the value to fetch_tags function
foreach($input as $key => $value ){
fetch_tags($value, $tags);
}
return true;
}elseif(is_string($input)){
/**
* If its a string, we can preg_match now.
* \#\S+ means we will take any string which follows a #
* If we get any matches, we will store that result in $tags
*/
if(preg_match_all('#(\#\S+)#', $input, $matches)){
$tags = array_merge($tags, $matches[1]);
}
return true;
}
return false;
}
Example :
<?php
$form = array(
array(
"type" => "text",
"value" => "
Hello #name
How old are you? #age
How are you today? #condition"
),
array(
"type" => "font",
"family" => "Arial",
"size" => 6,
"weight" => "Bold"
)
);
$words = [];
fetch_tags($form, $words);
print_r($words);
Output would be :
Array
(
[0] => #name
[1] => #age
[2] => #condition
)

Text replace using array

I guys,
I would like replace a text adding specific links on specific words.
So, I created a dynamic array like this:
$replace = array (
"ferrari" => 'ferrari',
"ferrari 2" => 'ferrari 2'
etc.
)
I found a way to replace the text using:
preg_replace(array_keys($replace), array_values($replace), $subject)
but if in the $subject there is the string "ferrari 2" it will be replaced with
[ferrari] instead of [ferrari 2].
How can I do an exact match?
Thanks a lot!
You may use the following solution:
$s = "he has a ferrari and ferrari 2 and what not."; // SAMPLE STRING
$replace = array ( // REPLACEMENTS ARRAY
"ferrari" => 'ferrari',
"ferrari 2" => 'ferrari 2'
);
$keys = array_map('strlen', array_keys($replace)); // SORTING BY KEY LENGTH
array_multisort($keys, SORT_DESC, $replace); // IN DESCENDING ORDER
$pat = '~' . implode("|", array_keys($replace)) . '~'; // BUILDING A PATTERN
echo $pat . "\n"; // => ~ferrari 2|ferrari~ - matches either ferrari 2 or ferrari
$res = preg_replace_callback($pat, function($m) use ($replace) { // REPLACING...
return isset($replace[$m[0]]) ? $replace[$m[0]] : $m[0]; // IF THE KEY EXISTS,
}, $s); // REPLACE WITH VALUE, ELSE KEEP THE MATCH
echo $res; // => he has a ferrari and ferrari 2 and what not.
See the PHP demo
change the order to:
$replace = array (
"ferrari 2" => 'ferrari 2'
"ferrari" => 'ferrari',
)
Usually when you replace, just changing the order to where the smallest keys are last solves a lot.
I imagine that the var $subject is like this:
$subject = 'ferrari ferrari 2';
Try with this:
$replace = array (
"/ferrari(?!\s+\d+)/" => 'ferrari',
"/ferrari 2/" => 'ferrari 2'
);
echo preg_replace(array_keys($replace), array_values($replace), $subject);

loop through an array and apply preg_match

i need to walk through an multidimensional array and and check ONLY the title if not start with alphabetic , as the follow :
Array
(
[0] => Array
(
[letter] =>
[id] => 176
)
[1] => Array
(
[letter] => "
[id] => 175
)
.....etc
so i need to check only letter if not start with a-zA-z , i have try do that , but still have something missing ,,
$notMatch = array();
foreach ($data as $value) {
foreach ($value as $item['title']=>$d) {
if(!preg_match('/^[a-zA-Z]$/',$d)){
$notMatch[]=$d;
}
}
}
See below URL i think it is very help full to you.
Update:
Using preg_match on a multidimensional array to return key values arrays
Try it
<?php
$data = array(
"abc"=>array(
"label" => "abc",
"value" => "def",
"type" => "ghi",
"desc" => "jkl",
),
"def"=>array(
"label" => "mno",
"value" => "qrs",
"type" => "tuv",
"desc" => "wxyz",
),
);
$matches = array();
$pattern = "/a/i"; //contains an 'a'
//loop through the data
foreach($data as $key=>$value){
//loop through each key under data sub array
foreach($value as $key2=>$value2){
//check for match.
if(preg_match($pattern, $value2)){
//add to matches array.
$matches[$key]=$value;
//match found, so break from foreach
break;
}
}
}
echo '<pre>'.print_r($matches, true).'</pre>';
?>
I removed one foreach loop and changed your preg_match pattern, removed the start of string/line and end of string/line anchors.
This is how I did it:
// I'm assuming your data array looks something like this:
$data = array(array('title'=>'fjsdoijsdiojsd', 'id'=>3),
array('title'=>'oijijsd', 'id'=>5),
array('title'=>'09234032', 'id'=>3));
$notMatch = array();
foreach ($data as $value) {
if(!preg_match('/([a-zA-Z]).*/',$value['title'])){
$notMatch[]=$value['title'];
echo 'notmatch! ' . $value['title'];
}
}
However, it's quite possible that someone with more regex experience can get you a better pattern. :)
http://codepad.viper-7.com/dvUQoW

Array as folders

I did this code:
index.php:
$series = array(
"a" => array(
"b" => array(
"FOLD", "more_arrays.php"
),
"b2" => array(
)
)
);
function pre($a) { print "<pre>"; print_r($a); print "</pre>"; }
$string = "a,,,b";
$all_directions = explode(",,,", $string);
$all_directions = array_map("trim", $all_directions);
$b = ""; $g = 0;
foreach($all_directions as $v)
{
$b .= "['".str_replace(array("[", "]", "'", "\""), null, $v)."']";
$g++;
}
#eval('$where = $series'.$b.';');
if(isset($where[0]) && $where[0] == "FOLD")
{
// a[series], b[series], c[new_array]
require_once("./more_folders/".$where[1]);
print $g;
}
for($i = 0; $i <= sizeof($where); $i++)
{
}
pre($where);
more_array.php:
$series_in = array(
"c" => array(
"d" => array(
"bla" => array(),
"hey" => array(),
"ha" => array()
),
"d2" => array(
)
),
"c2" => array(
)
)
At $string I define which "folder" I want to see, for example if I write $string = "a"; it will show all the arrays inside "a".
key = the name of the folder, value = the subfolders inside the folder and those array.
Now: Because it's going to be a huge array, I want to separate it to many arrays.
If you see at the code, $series[a][b] direct lead to another array.
Now if I do $string = "a,,,b"; I want to see: "c" and "c2"
and if I do $string = "a,,,b,,,c"; I want to see: "d", "d2"
and if I do $string = "a,,,b,,,c,,,d"; I want to see all inside d ( "bla", "hey", "ha" ..)
How can I do this?
I'll bite...
You seem to have most of the parts. Basically you need to put them together in a loop.
You've $string and $series. Then you split $string into your $all_directions. Loop thru $all_directions, each time diving down into the array $series = $series[$all_directions[$i]]; When you've done the last $all_directions return $series (but watch for running out of $series, return null, or false if you're sure that would be an error).
The only other thing is any time $series[$all_directions[$i]] is the special "FOLD" entry then first load the file and assign it on-the-fly something like
include ...;
$series[$all_directions[$i]] = $series_in;
You don't want and don't need eval() and the loop is better using for because you need to check "FOLD" in the key (I'd also say use a recursive function but you said the array can be very big so it might hurt performance).

Using preg_match on a multidimensional array to return key values arrays

I have an array that is structured as such:
$data = array(
"abc"=>array(
"label" => "abc",
"value" => "def",
"type" => "ghi",
"desc" => "jkl",
),
"def"=>array(
"label" => "mno",
"value" => "qrs",
"type" => "tuv",
"desc" => "wxyz",
),
);
I want to use preg_match with a foreach loop to perform a search on the arrays contained in $data and return the nested arrays of key value pairs.
for the googlers out there here's the better code
$data = <as above>
$pattern = "/whatever/";
$matches = array_filter($data, function($a) use($pattern) {
return preg_grep($pattern, $a);
});
Something like this?
<?php
$data = array(
"abc"=>array(
"label" => "abc",
"value" => "def",
"type" => "ghi",
"desc" => "jkl",
),
"def"=>array(
"label" => "mno",
"value" => "qrs",
"type" => "tuv",
"desc" => "wxyz",
),
);
$matches = array();
$pattern = "/a/i"; //contains an 'a'
//loop through the data
foreach($data as $key=>$value){
//loop through each key under data sub array
foreach($value as $key2=>$value2){
//check for match.
if(preg_match($pattern, $value2)){
//add to matches array.
$matches[$key]=$value;
//match found, so break from foreach
break;
}
}
}
echo '<pre>'.print_r($matches, true).'</pre>';
?>
If you are using PHP 5.5 and are viewing this question in 2015, this might be a more simple answer:
$elements= array_column($array, 1); //Where 1 is the name of the column or the index
$foundElements = preg_grep("/regex/i", $elements);
None of the answers above worked on my case, so I'll leave my solution here maybe it can be useful to someone
function multidimensionalArrayScan($arr, $pattern, &$result = []) : Array
{
foreach ($arr as $key => $value) {
if (is_array($arr[$key])) {
self::multidimensionalArrayScan($arr[$key], $pattern, $result);
continue;
}
$match = preg_match($pattern, $value);
if (!empty($match))
$result[$key] = $value;
}
return $result;
}
$data = <as above>
$pattern = "/whatever/";
multidimensionalArrayScan($data, $pattern);
$c=['abccd','123','12qw']; // where u'll search
$a = Array('/a/i', '/\d/i', '/\d+\w/i'); // what is
$b = array_map(function($a,$c){return (preg_match_all($a,$c,$m))? ($m[0][0]) : '';}, $a,$c);
print_r($b);
preg_grep('/needle/iu', array_column($haystack, "columnName", "keyName" ) );
Case-insensitive unicode grep on column columnName in array $haystack
preg_match_all returns the rows that match a pattern with a specific column name.
$pattern = "/REDUCTION/i";
$reductions = array_filter($data, function($a) use($pattern) {
return preg_match_all($pattern, $a['budget']);
});

Categories