PHP how to convert a complicated Pattern String into 2 Arrays? - php

I have a String in this format
{value=very big +$5},{value=super big +$10},{value=extra big +$15}
How to convert them into 2 Arrays in such format?
For example:
$name=["very big","super big","extra big"];
$price=["5","10","15"]; // OR $price=[5,10,15];
I can do that by using explode() if the string format is in a simpler format. However, this format is too complicated. Anyone knows how to do that ?

use explode with ',' ,'=' ,'+$'
$string = "{value=very big +$5},{value=super big +$10},{value=extra big +$15}";
$temp_array = (explode(",",$string));
foreach($temp_array as $val)
{
$temp_array = (explode("=",$val));
$temp_string = $temp_array[1];
$temp_string = str_replace("}","",$temp_string);
$temp_array = (explode("+$",$temp_string));
$name[] = $temp_array[0];
$price[] = $temp_array[1];
}
DEMO

You may try it like the Snippet below suggests. Quick-Test: Here.
<?php
$string = '{value=very big +$5},{value=super big +$10},{value=extra big +$15}';
$arrParts = explode(',', $string);
$name = [];
$price = [];
$result = [];
foreach($arrParts as $iKey=>$part){
$block = preg_replace(["#^\{.*?=#", "#\}$#"], "", $part);
$segments = preg_split("#\s#", $block); //<== CREATE AN ARRAY WITH 3 COLUMNS
list($val1, $val2, $val3) = $segments;
$namePart = $val1 . " {$val2}";
$pricePart = preg_replace("#[\+\-\$]#", "",$val3);
$name[] = $namePart;
$price[] = $pricePart;
// BONUS: JUST CREATE A 3RD ARRAY WITH NAMED-KEY
$result[$namePart] = $pricePart;
}
var_dump($name);
//YIELDS::
array (size=3)
0 => string 'very big' (length=8)
1 => string 'super big' (length=9)
2 => string 'extra big' (length=9)
var_dump($price);
//YIELDS::
array (size=3)
0 => string '5' (length=1)
1 => string '10' (length=2)
2 => string '15' (length=2)
var_dump($result);
//YIELDS::
array (size=3)
'very big' => string '5' (length=1)
'super big' => string '10' (length=2)
'extra big' => string '15' (length=2)

You can use regex, for example this should work:
preg_match_all('/value=([\w\s]+)\s\+/', $string, $matches)
preg_match_all('/\$([\d]+)\}/', $string, $matches)

Related

Foreach loop always add first character of string to the array

I am making a function that can help me to cast the string to array, but that strange when the function always add first character to the array. Thank at first and this is code i used in function:
$string = '0:009987;1:12312;2:45231;3:00985;3:10923;4:11253;4:62341;4:01102;4:58710;4:10102;4:87093;4:12034;5:9801;6:1092;6:4305;6:1090;7:450;8:34';
$explodedString = explode(';', $string);
//var_dump($explodedString);
$takeArray = array();
$counti = 0;
foreach($explodedString as $exploded){
$secondExp = explode(':', $exploded);
var_dump($secondExp);
if(isset($takeArray[$secondExp[0]])){
$takeArray[$secondExp[0]][$counti] = $secondExp[1];
}else{
$takeArray[$secondExp[0]] = $secondExp[1];
}
$counti++;
}
var_dump($takeArray);
This is current output of this code:
array (size=9)
0 => string '009987' (length=6)
1 => string '12312' (length=5)
2 => string '45231' (length=5)
3 => string '00981' (length=5)
4 => string '11253 605181' (length=12)
5 => string '9801' (length=4)
6 => string '1092 41' (length=16)
7 => string '450' (length=3)
8 => string '34' (length=2)
Looking into row 4 you will see the string: '605181', this string come from the first character of each value belong to 4. But i need an output array like this:
[0] => {'009987'},
....
[4] => { '11253', '62341', ...., },
....
Please help me.
I'm not sure why you need $counti. All you need to do is, initialize the $takeArray[$n] if it doesn't exists, and push a new value to it. Something like this:
if(!isset($takeArray[$secondExp[0]])) {
// Initialize the array
$takeArray[$secondExp[0]] = array();
}
// Push the new value to the array
$takeArray[$secondExp[0]][] = $secondExp[1];
You only need to do the following :
$takeArray = array();
foreach($explodedString as $exploded) {
$secondExp = explode(':', $exploded);
$takeArray[(int)$secondExp[0]][] = $secondExp[1];
}
$string = '0:009987;1:12312;2:45231;3:00985;3:10923;4:11253;4:62341;4:01102;4:58710;4:10102;4:87093;4:12034;5:9801;6:1092;6:4305;6:1090;7:450;8:34';
$explodedString = explode(';', $string);
$takeArray = array();
foreach($explodedString as $exploded)
{
$secondExp = explode(':', $exploded);
$takeArray[$secondExp[0]][] = $secondExp[1];
}
var_dump($takeArray);

Elements combination of same array in PHP

In my project, i will have to receive a string from user (in textarea). Now this string will be converted into array. Now the problem is that, the character length must be minimum of 3,
in the following array next element should be joined to current one if character length is less than 3. How to perform it in PHP.
a[0]=>this a[1]=>is a[2]=>an a[3]=>example a[4]=>array.
Output should be:
a[0]=>this a[1]=>isan a[2]=>example a[3]=>array.
Just try with:
$input = ['this', 'is', 'an', 'example', 'array.'];
$output = [];
$part = '';
foreach ($input as $value) {
$part .= $value;
if (strlen($part) > 3) {
$output[] = $part;
$part = '';
}
}
Output:
array (size=4)
0 => string 'this' (length=4)
1 => string 'isan' (length=4)
2 => string 'example' (length=7)
3 => string 'array.' (length=6)

alternative to eval('$array_test = array('.$test.');')

I'm looking for an alternative to
$test = "1=>'msg_test1',3=>'msg_test2',9=>'msg_test3'";
eval('$array_test = array('.$test.');');
does anyone have an idea how i can make it to have an array in a secure way from a string?
Thanks in advance for your help!
You could parse it manually with explode() like so:
$test = "1=>'msg_test1,3=>'msg_test2,9=>'msg_test3'";
$array_test = array();
foreach(explode(',', substr($test, 0, -1)) as $row)
{
$split = explode('=>\'', $row);
$array_test[$split[0]] = $split[1];
}
var_dump($array_test);
Produces:
array (size=3)
1 => string 'msg_test1' (length=9)
3 => string 'msg_test2' (length=9)
9 => string 'msg_test3' (length=9)
If I understand your question then you cshould format your string like this
$test = "value1,value2,value2";
Then proceed with and explode
$array_test = explode(',', $test);
your array
$array_test = array(
'1' => 'value1'
'2' => 'value2'
'3' => 'value3'
);

Convert Regular Expression to get words instead of characters

I have the following regular expression:
preg_match_all("/.{0,40}<b>(.+?)<\/b>.{0,40}/i", $string, $matches);
Currently as it is, it grabs 40 characters before the bold, and 40 characters after the bold. What can I do to change it from characters to words. How can I get is so it gets 20 words before the bold and 20 words after the bold?
Here is an example snippet of a string:
Tags are add by using either the keyword "in" or "<b>tagged</b>". Spiderman This will find all results containing
$str0 = 'Tags are add by using either the keyword "in" or "<b>tagged</b>". Spiderman This will find all results containing';
$len0 = strlen($str0);
preg_match_all('/<b>.+?<\/b>/i', $str0, $matches);
$str1 = $matches[0][0];
$len1 = strlen($str1);
$len2 = strpos($str0, $matches[0][0]);
$str2 = substr($str0, 0, $len2);
$len3 = $len0 - $len1 - $len2;
$str3 = substr($str0, $len1+$len2, $len3);
$arr1 = array_reverse(explode(' ', $str2));
$arr2 = explode(' ', $str3);
$key1 = count($arr1) - 1;
$key2 = count($arr2) - 1;
$i = 0;
$before = array();
while($i < $key1 && count($before) < 20) {
if (preg_match('/\w/', $arr1[$i])) {
$before[] = $arr1[$i];
}
$i++;
}
$i = 0;
$after = array();
while($i < $key2 && count($after) < 20) {
if (preg_match('/\w/', $arr2[$i])) {
$after[] = $arr2[$i];
}
$i++;
}
var_dump($before);
var_dump($after);
Although it is kinda long code, but it really works:
array:before (size=9)
0 => string 'or' (length=2)
1 => string '"in"' (length=4)
2 => string 'keyword' (length=7)
3 => string 'the' (length=3)
4 => string 'either' (length=6)
5 => string 'using' (length=5)
6 => string 'by' (length=2)
7 => string 'add' (length=3)
8 => string 'are' (length=3)
array:after (size=6)
0 => string 'Spiderman' (length=9)
1 => string 'This' (length=4)
2 => string 'will' (length=4)
3 => string 'find' (length=4)
4 => string 'all' (length=3)
5 => string 'results' (length=7)
Try this to get 20 words before and after bold.
/(?:[^\s]+\s){0,20}<b>(.+?)<\/b>(?:[^\s]+\s){0,20}/i

urldecode losses 1 parameter

I'm using urlencode & urldecode to pass variables trough a html-form.
$info = 'tempId='.$rows['tempID'].'&tempType='.$rows['tempType'].'&dbId='.$rows['ID'];
echo '<input type="hidden" name="rank[]" value="'.urlencode($info).'" >';
Here is what is in $rows
array (size=4)
'ID' => string '110' (length=3)
'tempID' => string '1' (length=1)
'tempType' => string 'temp_first' (length=10)
'pageOrder' => string '0' (length=1)
So $info is
tempId=1&tempType=temp_first&dbId=110
But if i then decode it, it losses 1 parameter. How is this possible?
foreach (explode('&', urldecode($list[$i])) as $chunk) {
$param = explode("=", $chunk);
$tempId = urldecode($param[0]); // template id
$tempType = urldecode($param[1]); // Template type
$dbId = urldecode($param[2]); // database ID
var_dump($param);
}
Output:
array (size=2)
0 => string 'dbId' (length=4)
1 => string '110' (length=3)
Sometime there are even things in the array wich should not be in there, for example instead of temp_first it says tempType. Just the variable name.
I hope you guys can help me
There's no need to explode and process the string manually, you can use parse_str():
parse_str(urldecode($list[$i]), $output);
var_dump($output);
Would output:
array
'tempId' => string '1' (length=1)
'tempType' => string 'temp_first' (length=10)
'dbId' => string '110' (length=3)
try this
$result=array();
foreach (explode('&', urldecode($list[$i])) as $chunk) {
$param = explode("=", $chunk);
$result[$param[0]]=$param[1];
}
var_dump($result);
Could you try this and check the result (I'm groping in the dark though):
//change this <input type="hidden" name="rank[]" value="'.urlencode($info).'" > to
//<input type="hidden" name="urlargs" value="'.urlencode($info).'" >
$values = explode('&',urldecode($_POST['urlargs']));
$arguments = array();
foreach($values as $argument_set){
$data = explode('=',$argument_set);
$arguments[$data[0]] = $data[1];
}
var_dump($arguments);
I believe the problem is in the way you're processing the value
$data=array();
foreach (explode('&', urldecode($list[$i])) as $chunk) {
$param = explode("=", $chunk); //
$data[$param[0]]=$param[1]
}
Instead of grouping all code together, start by putting it in seperate vars and echo the content for debugging. Because you are saying you loose one variable, but the output you show is just one of the variables. What is the var_dump of the other two?
Because your var_dump($param); would output the part before the '=' and after the '=', so indeed i would expect the output to be something like: So which one of these are you missing?
array (size=2)
0 => string 'tempId' (length=6)
1 => string '1' (length=1)
array (size=2)
0 => string 'tempType' (length=8)
1 => string 'temp_first' (length=10)
array (size=2)
0 => string 'dbId' (length=4)
1 => string '110' (length=3)
DEBUG code:
foreach ($list as $row) {
echo 'Full row:: '. $row.'<br>';
//if the data is comming via GET or POST, its already decoded and no need to do it again
$split = explode('&', urldecode($row));
foreach($split as $chunk) {
echo 'Chunk:: '.$chunk.'<br>';
$param = explode('=', $chunk);
echo 'param name:: '.$param[0].'<br>';
echo 'param value:: '.$param[1].'<br>';
}
}

Categories