This question already has answers here:
How to split a string by multiple delimiters in PHP?
(4 answers)
Closed 12 months ago.
Can we do multiple explode() in PHP?
For example, to do this:
foreach(explode(" ",$sms['sms_text']) as $no)
foreach(explode("&",$sms['sms_text']) as $no)
foreach(explode(",",$sms['sms_text']) as $no)
All in one explode like this:
foreach(explode('','&',',',$sms['sms_text']) as $no)
What's the best way to do this? What I want is to split the string on multiple delimiters in one line.
If you're looking to split the string with multiple delimiters, perhaps preg_split would be appropriate.
$parts = preg_split( '/(\s|&|,)/', 'This and&this and,this' );
print_r( $parts );
Which results in:
Array (
[0] => This
[1] => and
[2] => this
[3] => and
[4] => this
)
Here is a great solution I found at PHP.net:
<?php
//$delimiters must be an array.
function multiexplode ($delimiters,$string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return $launch;
}
$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";
$exploded = multiexplode(array(",",".","|",":"),$text);
print_r($exploded);
//And output will be like this:
// Array
// (
// [0] => here is a sample
// [1] => this text
// [2] => and this will be exploded
// [3] => this also
// [4] => this one too
// [5] => )
// )
?>
you can use this
function multipleExplode($delimiters = array(), $string = ''){
$mainDelim=$delimiters[count($delimiters)-1]; // dernier
array_pop($delimiters);
foreach($delimiters as $delimiter){
$string= str_replace($delimiter, $mainDelim, $string);
}
$result= explode($mainDelim, $string);
return $result;
}
You could use preg_split() function to stplit a string using a regular expression, like so:
$text = preg_split('/( |,|&)/', $text);
I'd go with strtok(), eg
$delimiter = ' &,';
$token = strtok($sms['sms_text'], $delimiter);
while ($token !== false) {
echo $token . "\n";
$token = strtok($delimiter);
}
Related
This question already has answers here:
Convert backslash-delimited string into an associative array
(4 answers)
Closed 2 years ago.
How to convert a string to an array in PHP? I've a string like this:
$str = "php/127/typescript/12/jquery/120/angular/50";
The output:
Array (
[php]=> 127
[typescript]=> 12
[jquery]=> 120
[angular]=> 50
)
You can use preg_match_all (Regular Expression), and array_combine:
RegEx used : ([^\/]*?)\/(\d+), eplanation here (by RegEx101)
$str = "php/127/typescript/12/jquery/120/angular/50";
#match string
preg_match_all("/([^\/]*?)\/(\d+)/", $str, $match);
#then combine match[1] and match[2]
$result = array_combine($match[1], $match[2]);
print_r($result);
Demo (with steps) : https://3v4l.org/blZhU
One approach might be to use preg_match_all to extract the keys and values from the path separately. Then, use array_combine to build the hashmap:
$str = "php/127/typescript/12/jquery/120/angular/50";
preg_match_all("/[^\W\d\/]+/", $str, $keys);
preg_match_all("/\d+/", $str, $vals);
$mapped = array_combine($keys[0], $vals[0]);
print_r($mapped[0]);
This prints:
Array
(
[0] => php
[1] => typescript
[2] => jquery
[3] => angular
)
You can use explode() with for()Loop as below:-
<?php
$str = 'php/127/typescript/12/jquery/120/angular/50';
$list = explode('/', $str);
$list_count = count($list);
$result = array();
for ($i=0 ; $i<$list_count; $i+=2) {
$result[ $list[$i] ] = $list[$i+1];
}
print_r($result);
?>
Output:-
Array
(
[php] => 127
[typescript] => 12
[jquery] => 120
[angular] => 50
)
Demo Here :- https://3v4l.org/8PQhd
This question already has answers here:
PHP: explode but ignore escaped delimiter
(4 answers)
Closed 3 years ago.
The text is
a,b,c,d\,e,f,g
and I want to split these into an array based on delimiter , and ignore the escaped , like \,e
["a","b","c", "d,e", "f", "g"]
I've tried using explode like
explode(',', $data);
but it doesn't recognize the escaped \ in the text.
How to split the text and ignore the escaped delimiter?
You can use preg_split to split based on un-escaped commas (using a negative look-behind on the comma to check it is not preceded by a \), although you would need to post-process to remove the backslashes:
$string = 'a,b,c,d\,e,f,g';
$array = preg_split('/(?<!\\\\),/', $string);
$array = array_map(function ($v) { return str_replace('\\', '', $v); }, $array);
print_r($array);
Output:
Array ( [0] => a [1] => b [2] => c [3] => d,e [4] => f [5] => g )
You can use regular expression for this, and they are quite good, but they are also quite hard to understand. Why not something more simplistic like:
$input = "a,b,c,d\,e,f,g,h\,i\,j,k,l,m";
$output = [];
$buffer = "";
foreach (explode(",", $input) as $part) {
if (substr($part, -1) == "\\") $buffer .= $part;
else {
$output[] = $buffer . $part;
$buffer = "";
}
}
print_r($output);
This doesn't remove the backslashes, but it is now easy to add or remove that. This is the same algorithm that removes them:
foreach (explode(",", $input) as $part) {
if (substr($part, -1) == "\\") $buffer .= substr($part, 0, -1) . ',';
else {
$output[] = $buffer . $part;
$buffer = "";
}
}
I am aware that this is not a popular opinion, but changing something you can actually easy understand is a lot more fun than struggling to understand dense regular expressions. It's, of course, all quite subjective.
Wihout regular expression
$ignore = '\\';
$arr = explode(',','a,b,c,d\,e,f,g');
array_walk($arr, function(&$v, $k) use ($ignore,&$arr){
if(strpos($v, $ignore)){
$v = str_replace($ignore, ',', $v).$arr[$k+1];
unset($arr[$k+1]);
}
return $v;
});
try this
$string = 'a,b,c,d\,e,f,g';
$str = str_replace("\,", '\\', $string);
$array = explode(',', $str);
print_r(str_replace('\\',',',$array));
result
Array
(
[0] => a
[1] => b
[2] => c
[3] => d,e
[4] => f
[5] => g
)
Here is my code, which currently does not working properly. How can I make it working? My wish is to make output like one string (of course I know how to "convert" array to string):
words altered, added, and removed to make it
Code:
<?php
header('Content-Type: text/html; charset=utf-8');
$text = explode(" ", strip_tags("words altered added and removed to make it"));
$stack = array();
$words = array("altered", "added", "something");
foreach($words as $keywords){
$check = array_search($keywords, $text);
if($check>(-1)){
$replace = " ".$text[$check].",";
$result = str_replace($text[$check], $replace, $text);
array_push($stack, $result);
}
}
print_r($stack);
?>
Output:
Array
(
[0] => Array
(
[0] => words
[1] => altered,
[2] => added
[3] => and
[4] => removed
[5] => to
[6] => make
[7] => it
)
[1] => Array
(
[0] => words
[1] => altered
[2] => added,
[3] => and
[4] => removed
[5] => to
[6] => make
[7] => it
)
)
Without more explanation it's as simple as this:
$text = strip_tags("words altered added and removed to make it");
$words = array("altered", "added", "something");
$result = $text;
foreach($words as $word) {
$result = str_replace($word, "$word,", $result);
}
Don't explode your source string
Loop the words and replace the word with the word and added comma
Or abandoning the loop approach:
$text = strip_tags("words altered added and removed to make it");
$words = array("altered", "added", "something");
$result = preg_replace('/('.implode('|', $words).')/', '$1,', $text);
Create a pattern by imploding the words on the alternation (OR) operator |
Replace found word with the word $1 and a comma
You can use an iterator
// Array with your stuff.
$array = [];
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $value) {
echo $v, " ";
}
Your original approach should work with a few modifications. Loop over the words in the exploded string instead. For each one, if it is in the array of words to modify, add the comma. If not, don't. Then the modified (or not) word goes on the stack.
$text = explode(" ", strip_tags("words altered added and removed to make it"));
$words = array("altered", "added", "something");
foreach ($text as $word) {
$stack[] = in_array($word, $words) ? "$word," : $word;
}
$str = "This is a string";
$words = explode(" ", $str);
Works fine, but spaces still go into array:
$words === array ('This', 'is', 'a', '', '', '', 'string');//true
I would prefer to have words only with no spaces and keep the information about the number of spaces separate.
$words === array ('This', 'is', 'a', 'string');//true
$spaces === array(1,1,4);//true
Just added: (1, 1, 4) means one space after the first word, one space after the second word and 4 spaces after the third word.
Is there any way to do it fast?
Thank you.
For splitting the String into an array, you should use preg_split:
$string = 'This is a string';
$data = preg_split('/\s+/', $string);
Your second part (counting spaces):
$string = 'This is a string';
preg_match_all('/\s+/', $string, $matches);
$result = array_map('strlen', $matches[0]);// [1, 1, 4]
Here is one way, splitting the string and running a regex once, then parsing the results to see which segments were captured as the split (and therefore only whitespace), or which ones are words:
$temp = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
if( strlen( trim( $item)) === 0) {
$spaces[] = strlen( $item);
} else {
$result[] = $item;
}
return $result;
}, array());
You can see from this demo that $words is:
Array
(
[0] => This
[1] => is
[2] => a
[3] => string
)
And $spaces is:
Array
(
[0] => 1
[1] => 1
[2] => 4
)
You can use preg_split() for the first array:
$str = 'This is a string';
$words = preg_split('#\s+#', $str);
And preg_match_all() for the $spaces array:
preg_match_all('#\s+#', $str, $m);
$spaces = array_map('strlen', $m[0]);
Another way to do it would be using foreach loop.
$str = "This is a string";
$words = explode(" ", $str);
$spaces=array();
$others=array();
foreach($words as $word)
{
if($word==' ')
{
array_push($spaces,$word);
}
else
{
array_push($others,$word);
}
}
Here are the results of performance tests:
$str = "This is a string";
var_dump(time());
for ($i=1;$i<100000;$i++){
//Alma Do Mundo - the winner
$rgData = preg_split('/\s+/', $str);
preg_match_all('/\s+/', $str, $rgMatches);
$rgResult = array_map('strlen', $rgMatches[0]);// [1,1,4]
}
print_r($rgData); print_r( $rgResult);
var_dump(time());
for ($i=1;$i<100000;$i++){
//nickb
$temp = preg_split('/(\s+)/', $str, -1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
if( strlen( trim( $item)) === 0) {
$spaces[] = strlen( $item);
} else {
$result[] = $item;
}
return $result;
}, array());
}
print_r( $words); print_r( $spaces);
var_dump(time());
int(1378392870)
Array
(
[0] => This
[1] => is
[2] => a
[3] => string
)
Array
(
[0] => 1
[1] => 1
[2] => 4
)
int(1378392871)
Array
(
[0] => This
[1] => is
[2] => a
[3] => string
)
Array
(
[0] => 1
[1] => 1
[2] => 4
)
int(1378392873)
$financialYear = 2015-2016;
$test = explode('-',$financialYear);
echo $test[0]; // 2015
echo $test[1]; // 2016
Splitting with regex has been demonstrated well by earlier answers, but I think this is a perfect case for calling ctype_space() to determine which result array should receive the encountered value.
Code: (Demo)
$string = "This is a string";
$words = [];
$spaces = [];
foreach (preg_split('~( +)~', $string, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $s) {
if (ctype_space($s)) {
$spaces[] = strlen($s);
} else {
$words[] = $s;
}
}
var_export([
'words' => $words,
'spaces' => $spaces
]);
Output:
array (
'words' =>
array (
0 => 'This',
1 => 'is',
2 => 'a',
3 => 'string',
),
'spaces' =>
array (
0 => 1,
1 => 1,
2 => 4,
),
)
If you want to replace the piped constants used by preg_split() you can just use 3 (Demo). This represents PREG_SPLIT_NO_EMPTY which is 1 plus PREG_SPLIT_DELIM_CAPTURE which is 2. Be aware that with this reduction in code width, you also lose code readability.
preg_split('~( +)~', $string, -1, 3)
What about this? Does someone care to profile this?
$str = str_replace(["\t", "\r", "\r", "\0", "\v"], ' ', $str); // \v -> vertical space, see trim()
$words = explode(' ', $str);
$words = array_filter($words); // there would be lots elements from lots of spaces so skip them.
I want to implode a string with multiple delimiters. I've already eplode it with this PHP function:
function multiexplode ($delimiters,$string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return $launch;
}
$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";
$exploded = multiexplode(array(",",".","|",":"),$text);
The output of this is:
Array (
[0] => here is a sample
[1] => this text
[2] => and this will be exploded
[3] => this also
[4] => this one too
[5] => )
)
Can I implode this array with the following multiple delimiters: , . | : ?
Edit:
For define the rules I think this is the best option:
$test = array(':', ',', '.', '|', ':');
$i = 0;
foreach ($exploded as $value) {
$exploded[$i] .= $test[$i];
$i++;
}
$test2 = implode($exploded);
The output of $test2 is:
here is a sample: this text, and this will be exploded. this also | this one too :)
I only now need to know how to define the $test array (maybe with preg_match()?) so that it matched these values , . | : and set the variables in a order where it occurs in the string into an array. Is this possible?
function multiexplode ($delimiters,$string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return $launch;
}
$string = "here is a sample: this text, and this will be exploded. this also | this one too :)";
echo "Input:".PHP_EOL.$string;
$needle = array(",",".","|",":");
$split = multiexplode($needle, $string);
$chars = implode($needle);
$found = array();
while (false !== $search = strpbrk($string, $chars)) {
$found[] = $search[0];
$string = substr($search, 1);
}
echo PHP_EOL.PHP_EOL."Found needle:".PHP_EOL.PHP_EOL;
print_r($found);
$i = 0;
foreach ($split as $value) {
$split[$i] .= $found[$i];
$i++;
}
$output = implode($split);
echo PHP_EOL."Output:".PHP_EOL.$output;
The output of this is:
Input:
here is a sample: this text, and this will be exploded. this also | this one too :)
Found needle:
Array
(
[0] => :
[1] => ,
[2] => .
[3] => |
[4] => :
)
Output:
here is a sample: this text, and this will be exploded. this also | this one too :)
You can see it working here.
For more information what's the function of strpbrk in this script, see here.
It's my first contribution to Stack Overflow, hope it helps.