How can I explode a string on every third semicolon (;)?
example data:
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
Desired output:
$output[0] = 'piece1;piece2:piece3;'
$output[1] = 'piece4;piece5;piece6;'
$output[2] = 'piece7;piece8;'
I am sure you can do something slick with regular expressions, but why not just explode the each semicolor and then add them three at a time.
$tmp = explode(";", $string);
$i=0;
$j=0;
foreach($tmp as $piece) {
if(! ($i++ %3)) $j++; //increment every 3
$result[$j] .= $piece;
}
Easiest solution I can think of is:
$chunks = array_chunk(explode(';', $input), 3);
$output = array_map(create_function('$a', 'return implode(";",$a);'), $chunks);
Essentially the same solution as the other ones that explode and join again...
$tmp = explode(";", $string);
while ($tmp) {
$output[] = implode(';', array_splice($tmp, 0, 3));
};
$string = "piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;piece9;";
preg_match_all('/([A-Za-z0-9\.]*;[A-Za-z0-9\.]*;[A-Za-z0-9\.]*;)/',$string,$matches);
print_r($matches);
Array
(
[0] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece4;piece5;piece6;
[2] => piece7;piece8;piece9;
)
[1] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece4;piece5;piece6;
[2] => piece7;piece8;piece9;
)
)
Maybe approach it from a different angle. Explode() it all, then combine it back in triples. Like so...
$str = "1;2;3;4;5;6;7;8;9";
$boobies = explode(";", $array);
while (!empty($boobies))
{
$foo = array();
$foo[] = array_shift($boobies);
$foo[] = array_shift($boobies);
$foo[] = array_shift($boobies);
$bar[] = implode(";", $foo) . ";";
}
print_r($bar);
Array
(
[0] => 1;2;3;
[1] => 4;5;6;
[2] => 7;8;9;
)
Here's a regex approach, which I can't say is all too good looking.
$str='';
for ($i=1; $i<20; $i++) {
$str .= "$i;";
}
$split = preg_split('/((?:[^;]*;){3})/', $str, -1,
PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
Output:
Array
(
[0] => 1;2;3;
[1] => 4;5;6;
[2] => 7;8;9;
[3] => 10;11;12;
[4] => 13;14;15;
[5] => 16;17;18;
[6] => 19;
)
Another regex approach.
<?php
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8';
preg_match_all('/([^;]+;?){1,3}/', $string, $m, PREG_SET_ORDER);
print_r($m);
Results:
Array
(
[0] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece3;
)
[1] => Array
(
[0] => piece4;piece5;piece6;
[1] => piece6;
)
[2] => Array
(
[0] => piece7;piece8
[1] => piece8
)
)
Regex Split
$test = ";2;3;4;5;6;7;8;9;10;;12;;14;15;16;17;18;19;20";
// match all groups that:
// (?<=^|;) follow the beginning of the string or a ;
// [^;]* have zero or more non ; characters
// ;? maybe a semi-colon (so we catch a single group)
// [^;]*;? again (catch second item)
// [^;]* without the trailing ; (to not capture the final ;)
preg_match_all("/(?<=^|;)[^;]*;?[^;]*;?[^;]*/", $test, $matches);
var_dump($matches[0]);
array(7) {
[0]=>
string(4) ";2;3"
[1]=>
string(5) "4;5;6"
[2]=>
string(5) "7;8;9"
[3]=>
string(6) "10;;12"
[4]=>
string(6) ";14;15"
[5]=>
string(8) "16;17;18"
[6]=>
string(5) "19;20"
}
<?php
$str = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
$arr = array_map(function ($arr) {
return implode(";", $arr);
}, array_chunk(explode(";", $str), 3));
var_dump($arr);
outputs
array(3) {
[0]=>
string(20) "piece1;piece2;piece3"
[1]=>
string(20) "piece4;piece5;piece6"
[2]=>
string(14) "piece7;piece8;"
}
Similar to #Sebastian's earlier answer, I recommend preg_split() with a repeated pattern. The difference is that by using a non-capturing group and appending \K to restart the fullstring match, you can spare writting the PREG_SPLIT_DELIM_CAPTURE flag.
Code: (Demo)
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
var_export(preg_split('/(?:[^;]*;){3}\K/', $string, 0, PREG_SPLIT_NO_EMPTY));
A similar technique for splitting after every 2 things can be found here. That snippet actually writes the \K before the last space character so that the trailing space is consumed while splitting.
Related
I'm get data string lat and long google maps polygon. I want to convert this value to array .
$value = "(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)";
I want the result like this Array :
$polygon = array(
array(-6.2811957386588855, 106.70141951079609),
array(-6.281142416506361, 106.70432702536823),
array(-6.2781776962328815, 106.70438066954853),
array(-6.2781776962328815, 106.70136586661579),
);
You can convert the string to valid JSON by converting parentheses to square brackets and adding a [] layer around the outside, and then json_decode it:
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
$polygon = json_decode('[' . str_replace(array('(', ')'), array('[', ']'), $value) . ']', true);
print_r($polygon);
Output:
Array
(
[0] => Array
(
[0] => -6.2811957386589
[1] => 106.7014195108
)
[1] => Array
(
[0] => -6.2811424165064
[1] => 106.70432702537
)
[2] => Array
(
[0] => -6.2781776962329
[1] => 106.70438066955
)
[3] => Array
(
[0] => -6.2781776962329
[1] => 106.70136586662
)
)
Demo on 3v4l.org
Using preg_match_all() and array_walk() you can parse the coordinates as an array
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
preg_match_all('/\(([0-9\-\s,.]+)\)/', $value, $matches);
array_walk($matches[1], function(&$val) { $val = explode(',', $val); });
$coordinates = $matches[1];
print_r($coordinates);
Using preg_match_all() get all the coordinates as array of string
Using array_walk() make an iteration over the coordinated array and explode by the delimiter of comma (,)
Working demo.
Regex demo.
You can use explode() function like this
$string = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
foreach(explode('),(',trim($string,'()')) as $single_array)
{
$sub_array= array();
foreach(explode(',',$single_array) as $sbs_array)
{
$sub_array[] = $sbs_array;
}
$result[] = $sub_array;
}
print_r ($result);
Output :
Array
(
[0] => Array
(
[0] => -6.2811957386588855
[1] => 106.70141951079609
)
[1] => Array
(
[0] => -6.281142416506361
[1] => 106.70432702536823
)
[2] => Array
(
[0] => -6.2781776962328815
[1] => 106.70438066954853
)
[3] => Array
(
[0] => -6.2781776962328815
[1] => 106.70136586661579
)
)
Demo : https://3v4l.org/6HEAG
You can use explode with trim and array_map
$r = explode('),(',trim($value,'()'));
$c = array_map(function($v){return explode(',',$v);}, $r);
print_r($c);
Working example : https://3v4l.org/fFAS0
I suggest using preg_match_all with array_map
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
preg_match_all('#\(([\-\d\.]+),\s+([\-\d\.]+)\)#', $value, $matches);
$geo = array_map(function ($a, $b) {
return [(float)$a, (float)$b];
}, $matches[1], $matches[2]);
Output:
array(4) {
[0]=>
array(2) {
[0]=> float(-6.2811957386589)
[1]=> float(106.7014195108)
}
[1]=>
array(2) {
[0]=> float(-6.2811424165064)
[1]=> float(106.70432702537)
}
[2]=>
array(2) {
[0]=> float(-6.2781776962329)
[1]=> float(106.70438066955)
}
[3]=>
array(2) {
[0]=> float(-6.2781776962329)
[1]=> float(106.70136586662)
}
}
Regex
Not sure how I would do this but if someone could point me in the right track that'll be great, basically I've got a lone line of text in a variable which looks like this:
Lambo 1; Trabant 2; Car 3;
Then I want to split "Lambo" to it's own variable then "1" to it's own variable, and repeat for the others. How would I go and do this?
I know about explode() but not sure how I would do it to split the variable up twice etc.
As requested in the comments my desired output would be like this:
$Item = "Lambo"
$Quantity = 1
Then echo them out and go back to top of loop for example and do the same for the Trabant and Car
<?php
$in = "Lambo 1; Trabant 2; Car 3;";
foreach (explode(";", $in) as $element) {
$element = trim($element);
if (strpos($element, " ") !== false ) {
list($car, $number) = explode(" ", $element);
echo "car: $car, number: $number";
}
}
You can use explode to split the input on each ;, loop over the results and then split over each .
You can use preg_split and iterate over the array by moving twice.
$output = preg_split("/ (;|vs) /", $input);
You could use preg_match_all for getting those parts:
$line = "Lambo 1; Trabant 2; Car 3;";
preg_match_all("/[^ ;]+/", $line, $matches);
$matches = $matches[0];
With that sample data, the $matches array will look like this:
Array ( "Lambo", "1", "Trabant", "2", "Car", "3" )
$new_data="Lambo 1;Trabant 2;Car 3;" ;
$new_array=explode(";", $new_data);
foreach ($new_array as $key ) {
# code...
$final_data=explode(" ", $key);
if(isset($final_data[0])){ echo "<pre>".$final_data[0]."</pre>";}
if(isset($final_data[1])){echo "<pre>".$final_data[1]."</pre>";}
}
This places each word and number in a new key of the array if you need to acess them seperatly.
preg_match_all("/(\w+) (\d+);/", $input_lines, $output_array);
Click preg_match_all
http://www.phpliveregex.com/p/fM8
Use a global regular expression match:
<?php
$subject = 'Lambo 1; Trabant 2; Car 3;';
$pattern = '/((\w+)\s+(\d+);\s?)+/Uu';
preg_match_all($pattern, $subject, $tokens);
var_dump($tokens);
The output you get is:
array(4) {
[0] =>
array(3) {
[0] =>
string(8) "Lambo 1;"
[1] =>
string(10) "Trabant 2;"
[2] =>
string(6) "Car 3;"
}
[1] =>
array(3) {
[0] =>
string(8) "Lambo 1;"
[1] =>
string(10) "Trabant 2;"
[2] =>
string(6) "Car 3;"
}
[2] =>
array(3) {
[0] =>
string(5) "Lambo"
[1] =>
string(7) "Trabant"
[2] =>
string(3) "Car"
}
[3] =>
array(3) {
[0] =>
string(1) "1"
[1] =>
string(1) "2"
[2] =>
string(1) "3"
}
}
In there the elements 2 and 3 hold exactly the tokens you are looking for.
I'm trying to split the following string:
Hello how are you<br>Foo bar hello
Into
"Hello", " how", " are", " you", "<br>", " Foo", " bar", " Hello"
Is this possible?
Don't make things harder than you have to. Use preg_split() with the PREG_SPLIT_DELIM_CAPTURE flag, and capture the <br>:
$str = 'Hello how are you<br>Foo bar hello';
$array = preg_split( '/\s+|(<br>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r( $array);
Output:
Array
(
[0] => Hello
[1] => how
[2] => are
[3] => you
[4] => <br>
[5] => Foo
[6] => bar
[7] => hello
)
Edit: To include the space in the following token, you can use an assertion:
$array = preg_split( '/(?:\s*(?=\s))|(<br>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
So, the goal of preg_split() is to find a spot in the string to split. The regex we use consists of two parts, OR'd together with |:
(?:\s*(?=\s)). This starts off with a non-capturing group (?:), because when we match this part of the regex, we do not want it returned to us. Inside the non-capturing group, is \s*(?=\s), which says "match zero or more whitespace characters, but assert that the next character is a whitespace character". Looking at our input string, this makes sense:
Hello how are you<br>Foo bar hello
^ ^
The regex will start from left to right, find "Hello{space}how", and decide how to split the string. It tries to match \s* with the restriction that if it consumes any space, there needs to be one space left. So, it breaks up the string at just "Hello". When it continues, it has " how are youFoo bar hello" left. It starts the match again, trying to match from where it left off, and sees " how are", and does the same split as above. It continues until there are no matches left.
Capture <br>, with (<br>). It is captured because when we match this, we want to keep it in the output, so capturing it along with the PREG_SPLIT_DELIM_CAPTURE causes it to be returned to us when it is matched (instead of being completely consumed).
This results in:
array(8)
{
[0]=> string(5) "Hello"
[1]=> string(4) " how"
[2]=> string(4) " are"
[3]=> string(4) " you"
[4]=> string(4) "<br>"
[5]=> string(3) "Foo"
[6]=> string(4) " bar"
[7]=> string(6) " hello"
}
Not pretty, but simple enough:
$data = 'Hello how are you<br>Foo bar hello';
$split = array();
foreach (explode('<br>', $data) as $line) {
$split[] = array_merge($split, explode(' ', $line));
$split[] = '<br>';
}
array_pop($split);
print_r($split);
Or version 2:
$data = 'Hello how are you<br>Foo bar hello';
$data = preg_replace('#\s|(<br>)#', '**$1**', $data);
$split = array_filter(explode('**', $data));
print_r($split);
This is how I'd do it:
Explode the string with space as a delimiter
Loop through the parts
Use strpos and check if part contains the given tag -- <br> in this case
If it does, explode the string again with the tag as the delimiter
Push all the three items into the result array
If it doesn't, then push it into the result array
Code:
$str = 'Hello how are you<br>Foo bar hello';
$parts = explode(' ', $str);
$result = array();
foreach ($parts as $part) {
if(strpos($part, '<br>') !== FALSE) {
$arr = explode('<br>', $part);
$result = array_merge($result, $arr);
$result[] = "<br>";
}
else {
$result[] = $part;
}
}
print_r($result);
Output:
Array
(
[0] => Hello
[1] => how
[2] => are
[3] => you
[4] => Foo
[5] => <br>
[6] => bar
[7] => hello
)
Demo!
Here is a brief solution. Replace <br> by (space <br> space) and split using space:
<?php
$newStr=str_replace("<br>"," <br> ","Hello how are you<br>Foo bar hello");
$str= explode(' ',$newStr);
?>
Output of print_r($str):
(
[0] => Hello
[1] => how
[2] => are
[3] => you
[4] => <br>
[5] => Foo
[6] => bar
[7] => hello
)
Borrowing the preg_split pattern from #nickb's answer:
<?php
$string = 'Hello how are you<br>Foo bar hello';
$array = preg_split('/\s/',$string);
foreach($array as $key => $value) {
$a = preg_split( '/\s+|(<br>)/', $value, -1, PREG_SPLIT_DELIM_CAPTURE);
if(is_array($a)) {
foreach($a as $key2 => $value2) {
$result[] = $value2;
}
}
}
print_r($result);
?>
Output:
Array
(
[0] => Hello
[1] => how
[2] => are
[3] => you
[4] => <br>
[5] => Foo
[6] => bar
[7] => hello
)
This question already has answers here:
Convert a comma-delimited string into array of integers?
(17 answers)
Closed 9 years ago.
Say I have a string like so $thestring = "1,2,3,8,2".
If I explode(',', $thestring) it, I get an array of strings. How do I explode it to an array of integers instead?
array_map also could be used:
$s = "1,2,3,8,2";
$ints = array_map('intval', explode(',', $s ));
var_dump( $ints );
Output:
array(5) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
[3]=> int(8)
[4]=> int(2)
}
Example codepad.
Use something like this:
$data = explode( ',', $thestring );
array_walk( $data, 'intval' );
http://php.net/manual/en/function.array-walk.php
For the most part you shouldn't really need to (PHP is generally good with handling casting strings and floats/ints), but if it is absolutely necessary, you can array_walk with intval or floatval:
$arr = explode(',','1,2,3');
// use floatval if you think you are going to have decimals
array_walk($arr,'intval');
print_r($arr);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
If you need something a bit more verbose, you can also look into settype:
$arr = explode(",","1,2,3");
function fn(&$a){settype($a,"int");}
array_walk($f,"fn");
print_r($f);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
That could be particularly useful if you're trying to cast dynamically:
class Converter {
public $type = 'int';
public function cast(&$val){ settype($val, $this->type); }
}
$c = new Converter();
$arr = explode(",","1,2,3,0");
array_walk($arr,array($c, 'cast'));
print_r($arr);
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
)
// now using a bool
$c->type = 'bool';
$arr = explode(",","1,2,3,0");
array_walk($arr,array($c, 'cast'));
var_dump($arr); // using var_dump because the output is clearer.
array(4) {
[0]=>
bool(true)
[1]=>
bool(true)
[2]=>
bool(true)
[3]=>
bool(false)
}
Since $thestring is an string then you will get an array of strings.
Just add (int) in front of the exploded values.
Or use the array_walk function:
$arr = explode(',', $thestring);
array_walk($arr, 'intval');
$thestring = "1,2,3,8,a,b,2";
$newArray = array();
$theArray = explode(",", $thestring);
print_r($theArray);
foreach ($theArray as $theData) {
if (is_numeric($theData)) {
$newArray[] = $theData;
}
}
print_r($newArray);
// Output
Original array
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 8 [4] => a [5] => b [6] => 2 )
Numeric only array
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 8 [4] => 2 )
$arr=explode(',', $thestring);
$newstr = '';
foreach($arr as $key=>$val){
$newstr .= $val;
}
I am trying to split a string into an array of word pairs in PHP. So for example if you have the input string:
"split this string into word pairs please"
the output array should look like
Array (
[0] => split this
[1] => this string
[2] => string into
[3] => into word
[4] => word pairs
[5] => pairs please
[6] => please
)
some failed attempts include:
$array = preg_split('/\w+\s+\w+/', $string);
which gives me an empty array, and
preg_match('/\w+\s+\w+/', $string, $array);
which splits the string into word pairs but doesn't repeat the word. Is there an easy way to do this? Thanks.
Why not just use explode ?
$str = "split this string into word pairs please";
$arr = explode(' ',$str);
$result = array();
for($i=0;$i<count($arr)-1;$i++) {
$result[] = $arr[$i].' '.$arr[$i+1];
}
$result[] = $arr[$i];
Working link
If you want to repeat with a regular expression, you'll need some sort of look-ahead or look-behind. Otherwise, the expression will not match the same word multiple times:
$s = "split this string into word pairs please";
preg_match_all('/(\w+) (?=(\w+))/', $s, $matches, PREG_SET_ORDER);
$a = array_map(
function($a)
{
return $a[1].' '.$a[2];
},
$matches
);
var_dump($a);
Output:
array(6) {
[0]=>
string(10) "split this"
[1]=>
string(11) "this string"
[2]=>
string(11) "string into"
[3]=>
string(9) "into word"
[4]=>
string(10) "word pairs"
[5]=>
string(12) "pairs please"
}
Note that it does not repeat the last word "please" as you requested, although I'm not sure why you would want that behavior.
You could explode the string and then loop through it:
$str = "split this string into word pairs please";
$strSplit = explode(' ', $str);
$final = array();
for($i=0, $j=0; $i<count($strSplit); $i++, $j++)
{
$final[$j] = $strSplit[$i] . ' ' . $strSplit[$i+1];
}
I think this works, but there should be a way easier solution.
Edited to make it conform to OP's spec. - as per codaddict
$s = "split this string into word pairs please";
$b1 = $b2 = explode(' ', $s);
array_shift($b2);
$r = array_map(function($a, $b) { return "$a $b"; }, $b1, $b2);
print_r($r);
gives:
Array
(
[0] => split this
[1] => this string
[2] => string into
[3] => into word
[4] => word pairs
[5] => pairs please
[6] => please
)