I have a string such as:
"0123456789"
And I need to split each character into an array.
I, for the hell of it, tried:
explode('', '123545789');
But it gave me the obvious: Warning: No delimiter defined in explode) ..
How would I come across this? I can't see any method off hand, especially just a function.
$array = str_split("0123456789bcdfghjkmnpqrstvwxyz");
str_split takes an optional 2nd param, the chunk length (default 1), so you can do things like:
$array = str_split("aabbccdd", 2);
// $array[0] = aa
// $array[1] = bb
// $array[2] = cc etc ...
You can also get at parts of your string by treating it as an array:
$string = "hello";
echo $string[1];
// outputs "e"
You can access characters in a string just like an array:
$s = 'abcd';
echo $s[0];
prints 'a'
Try this:
$str = '123456789';
$char_array = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
str_split can do the trick. Note that strings in PHP can be accessed just like a character array. In most cases, you won't need to split your string into a "new" array.
Here is an example that works with multibyte (UTF-8) strings.
$str = 'äbcd';
// PHP 5.4.8 allows null as the third argument of mb_strpos() function
do {
$arr[] = mb_substr( $str, 0, 1, 'utf-8' );
} while ( $str = mb_substr( $str, 1, mb_strlen( $str ), 'utf-8' ) );
It can be also done with preg_split() (preg_split( '//u', $str, null, PREG_SPLIT_NO_EMPTY )), but unlike the above example, that runs almost as fast regardless of the size of the string, preg_split() is fast with small strings, but a lot slower with large ones.
Try this:
$str = '546788';
$char_array = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
Try this:
$str = "Hello Friend";
$arr1 = str_split($str);
$arr2 = str_split($str, 3);
print_r($arr1);
print_r($arr2);
The above example will output:
Array
(
[0] => H
[1] => e
[2] => l
[3] => l
[4] => o
[5] =>
[6] => F
[7] => r
[8] => i
[9] => e
[10] => n
[11] => d
)
Array
(
[0] => Hel
[1] => lo
[2] => Fri
[3] => end
)
If you want to split the string, it's best to use:
$array = str_split($string);
When you have a delimiter, which separates the string, you can try,
explode('', $string);
Where you can pass the delimiter in the first variable inside the explode such as:
explode(',', $string);
$array = str_split("$string");
will actually work pretty fine, but if you want to preserve the special characters in that string, and you want to do some manipulation with them, then I would use
do {
$array[] = mb_substr($string, 0, 1, 'utf-8');
} while ($string = mb_substr($string, 1, mb_strlen($string), 'utf-8'));
because for some of mine personal uses, it has been shown to be more reliable when there is an issue with special characters.
Related
I need to cast $string = ("one","two","three,subthree","four") into PHP array like.
$data[0] => "one",
$data[1] => "two",
$data[2] => "three,subthree",
$data[3] => "four"
The issue is that the delimiter in 3rd variable contains comma so explode function is making the string into 5 variables instead of 4.
You can convert the string to JSON string and then decode like this
$string = '("one","two","three,subthree","four")';
$string = str_replace(['(', ')'], ['[', ']'], $string);
$array = json_decode($string, true);
print_r($array);
Working demo.
Edit:
If you have possibilities to have brackets [( or )] in string, you can trim by brackets [( or )] and explode by the delimiter ",". Example:
$string = '("one","two","three,subthree","four")';
$string = trim($string, ' ()');
$array = explode('","', $string);
print_r($array);
Another way is to use preg_match_all() by the patter ~"([^"])+"~
$string = '("one","two","three,subthree","four")';
preg_match_all('~"([^"]+)"~', $string, $array);
print_r($array[0]);
Regex explanation:
" matches a double quote
([^"]+) capturing group
[^"] any characters except double quote
+ one or more occurrence
" matches a double quote
Here's a shorter version to do that:
$string = '("one", "two,three")';
preg_match_all('/"([^"]+)"/', $string, $string);
echo "<pre>";
var_dump($string[1]);
Output:
array(2) {
[0]=>
string(3) "one"
[1]=>
string(9) "two,three"
}
You can use substr to remove the first (" and ") and then use explode:
$string = '("one","two","three,subthree","four")';
$s = substr($string,2,-2);
// now $s is: one","two","three,subthree","four
print_r(explode('","', $s));
Which outputs:
(
[0] => one
[1] => two
[2] => three,subthree
[3] => four
)
Live example: 3v4l
You can use explode with trim
$string = '("one","two","three,subthree","four")';
print_r(explode('","',trim($string,'"()')));
Working example : https://3v4l.org/4ZERb
A simple way which does the processing of quotes for you is to use str_getcsv() (after removing the start and end brackets)...
$string = '("one","two","three,subthree","four")';
$string = substr($string, 1, -1);
print_r(str_getcsv($string));
gives
Array
(
[0] => one
[1] => two
[2] => three,subthree
[3] => four
)
Main thing is that it will also work with...
$string = '("one","two","three,subthree","four",5)';
and output
Array
(
[0] => one
[1] => two
[2] => three,subthree
[3] => four
[4] => 5
)
After instructing clients to input only
number comma number comma number
(no set length, but generally < 10), the results of their input have been, erm, unpredictable.
Given the following example input:
3,6 ,bannana,5,,*,
How could I most simply, and reliably end up with:
3,6,5
So far I am trying a combination:
$test= trim($test,","); //Remove any leading or trailing commas
$test= preg_replace('/\s+/', '', $test);; //Remove any whitespace
$test= preg_replace("/[^0-9]/", ",", $test); //Replace any non-number with a comma
But before I keep throwing things at it...is there an elegant way, probably from a regex boffin!
In a purely abstract sense this is what I'd do:
$test = array_filter(array_map('trim',explode(",",$test)),'is_numeric')
Example:
http://sandbox.onlinephpfunctions.com/code/753f4a833e8ff07cd9c7bd780708f7aafd20d01d
<?php
$str = '3,6 ,bannana,5,,*,';
$str = explode(',', $str);
$newArray = array_map(function($val){
return is_numeric(trim($val)) ? trim($val) : '';
}, $str);
print_r(array_filter($newArray)); // <-- this will give you array
echo implode(',',array_filter($newArray)); // <--- this give you string
?>
Here's an example using regex,
$string = '3,6 ,bannana,5,-6,*,';
preg_match_all('#(-?[0-9]+)#',$string,$matches);
print_r($matches);
will output
Array
(
[0] => Array
(
[0] => 3
[1] => 6
[2] => 5
[3] => -6
)
[1] => Array
(
[0] => 3
[1] => 6
[2] => 5
[3] => -6
)
)
Use $matches[0] and you should be on your way.
If you don't need negative numbers just remove the first bit in the in the regex rule.
$str = "[10:42-23:10]part1[11:30-13:20]part2"
I wish to split it into something like:
[1] 10:42-23:10
[2] part1
[3] 11:30-13:20
[4] part2
The best I managed to come up with is:
$parts = preg_split("/(\\[*\\])\w+/", $str );
But this returns
[0] => [10:42-23:10
[1] => [11:30-13:20
[2] =>
Also you can use regex in preg_match_all() instead of preg_split()
$str = "[10:42-23:10]part1[11:30-13:20]part2";
preg_match_all("/[^\[\]]+/", $str, $parts);
print_r($parts[0]);
See result in demo
Split on alternative between [ and ], and use the flag PREG_SPLIT_NO_EMPTY to not catch empty parts.
$str = "[10:42-23:10]part1[11:30-13:20]part2";
$parts = preg_split("/\[|\]/", $str, -1, PREG_SPLIT_NO_EMPTY );
print_r($parts);
Output:
Array
(
[0] => 10:42-23:10
[1] => part1
[2] => 11:30-13:20
[3] => part2
)
NB.
Thank to #WiktorStribiżew , his regex /[][]/ is much more efficient, I've some benchmark, it is about 40% faster.
$str = "[10:42-23:10]part1[11:30-13:20]part2";
$parts = preg_split("/[][]/", $str, -1, PREG_SPLIT_NO_EMPTY );
print_r($parts);
Here is the perl script I have used to do the benchmark:
#!/usr/bin/perl
use Benchmark qw(:all);
my $str = "[10:42-23:10]part1[11:30-13:20]part2";
my $count = -5;
cmpthese($count, {
'[][]' => sub {
my #parts = split(/[][]/, $str);
},
'\[|\]' => sub {
my #parts = split(/\[|\]/, $str);
},
});
Result: (2 runs)
>perl -w benchmark.pl
Rate \[|\] [][]
\[|\] 536640/s -- -40%
[][] 891396/s 66% --
>Exit code: 0
>perl -w benchmark.pl
Rate \[|\] [][]
\[|\] 530867/s -- -40%
[][] 885242/s 67% --
>Exit code: 0
Use a simple regex to match any [...] substring (\[[^][]*]) and wrap the whole pattern with a capturing group - then you can use it with preg_split and PREG_SPLIT_DELIM_CAPTURE flag to get both the captures and the substrings in between matches:
$re = '/(\[[^][]*])/';
$str = '[10:42-23:10]part1[11:30-13:20]part2';
$matches = preg_split($re, $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($matches);
See the PHP demo
With this approach, you may have a better control of what you match inside square brackets, as you may adjust the pattern to only match time ranges, e.g.
(\[\d{2}:\d{2}-\d{2}:\d{2}])
A [10:42-23:10]part1[11:30-13:20]part2[4][5] will get split into [10:42-23:10], part1, [11:30-13:20] and part2[4][5] (note the [4][5] are not split out).
See this regex demo
Without regex, you can use strtok:
$result = [];
$tok = strtok($str, '[]');
do {
if (!empty($tok))
$result[] = $tok;
} while (false !== $tok = strtok('[]'));
I looked up splitting the string into array in google.I have found that str_split is working.By explode it's doesn't work in below condition.How can I split the string by explode()?
<?php
$string = "EEEE";
print_r(str_split($string));//Array ( [0] => E [1] => E [2] => E [3] => E )
print_r(explode("",$string));//Empty delimiter error
?>
As indicated by your error, explode requires a delimiter to split the string!
You should try,
$str = "EEEE";
$answer = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
alternative way would be preg_split.
$str="a,b,c,d-e,f,g,h"
I am trying to extract the strings from $str that are separated "," and are before "-" in one array and the strings separated by "," and are after "-" in second array. So that $arr1=array(a,b,c,d); and $arr2=array(e,f,g,h);. I am just using $str as an example and generally I want this to work for any string of the same form i.e. $str=s1,s2,s3,s4,s5,....-r1,r2,t3....
NOTE: If $str doesn't have "-" then $arr2 vanishes and $arr1 contains an array of the elements separated by ',' in $str.
This is what I tried
preg_match_all('~(^|.*,)(.*)(,.*|\-|$)~', $str, $arr1);
preg_match_all('~(-|.*,)(.*)(,.*|$)~', $str, $arr2);
However each array comes with one element that contains the string str.
Does anyone know why this is not working.
All of your regex patterns are not optimal and it seems the task is easier to solve with explode and array_map:
array_map() returns an array containing all the elements of array1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map()
$str="a,b,c,d-e,f,g,h";
$ex = array_map(function ($s) {
return explode(",", $s);
}, explode("-", $str));
print_r($ex);
See IDEONE demo
Results:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
)
[1] => Array
(
[0] => e
[1] => f
[2] => g
[3] => h
)
)
^(.*?(?=-|$))|(?<=-)(.*$)
You can use this to get 2 arrays.See demo.
https://regex101.com/r/vV1wW6/19
Your regex is not working as you have used greedy modifier..*, will stop at the last instance of ,
EDIT:
Use this is you want string after - to be in second group.
^(.*?(?=-|$))(?:-(.*$))?
https://regex101.com/r/vV1wW6/20
You can simply use preg_match to check does your string contains - if yes than can simply use array_walk like as
$str = 'a,b,c,d-e,f,g,h';
$result = [];
if(preg_match('/[-]/', $str)){
array_walk(explode('-',$str),function($v,$k)use(&$result){
$result[] = explode(',',$v);
});
}else{
array_walk(explode(',',$str),function($v,$k)use(&$result){
$result[] = $v;
});
}
print_r($result);
Without regex (the most reasonable way):
$str="a,b,c,d-e,f,g,h";
list($arr1, $arr2) = explode('-', $str);
$arr1 = explode(',', $arr1);
if ($arr2)
$arr2 = explode(',', $arr2);
else
unset($arr2);
With regex (for the challenge):
if (preg_match_all('~(?:(?!\G)|\A)([^-,]+)|-?([^,]+),?~', $str, $m)) {
$arr1 = array_filter($m[1]);
if (!$arr2 = array_filter($m[2]))
unset($arr2);
}