Created
September 24, 2013 01:54
-
-
Save pospi/6679400 to your computer and use it in GitHub Desktop.
Like PHP's implode() and explode(), but lets you escape the delimiters for splitting the strings with.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Same as implode, but escape the separator when it exists in the array elements being imploded | |
* If the separator is longer than 1 character, only the first character need be escaped (not every character of the delimiter). | |
* | |
* @param string $sep delimiter to stich the array together with | |
* @param array $arr array to combine | |
* @param char $escape escape character to escape any found delimiters with | |
* @return imploded string | |
* | |
* @author Sam Pospischil <[email protected]> | |
*/ | |
function escapedimplode($sep, $arr, $escape = '\\') { | |
if (!is_array($arr)) { | |
return false; | |
} | |
foreach ($arr as $k => $v) { | |
$arr[$k] = str_replace($sep, $escape . $sep, $v); | |
} | |
return implode($sep, $arr); | |
} | |
/** | |
* same as explode, but don't treat delimiters preceded by an escaped character as delimiters, and convert them in the output | |
* If the separator is longer than 1 character, only the first character need be escaped (not every character of the delimiter). | |
* | |
* @param string $sep boundary delimiter to split the input string on | |
* @param string $str string to explode | |
* @param char $escape escape character used to escape delimiters in the string | |
* @return exploded array, with delimiter escape characters removed | |
* | |
* @author Sam Pospischil <[email protected]> | |
*/ | |
function escapedexplode($sep, $str, $escape = '\\') { | |
$astr = str_split($str); | |
$result = array(); // final result array | |
$buffer = ''; // buffer for current array item match | |
$matchedBuffer = ''; // buffer for storing matched delimiters in case of a mismatch part-way | |
$wasEsc = false; // flag to ignore the current character if the previous one was an escape char | |
$sepLen = strlen($sep); // precomputed length of separator string, for efficiency | |
$matchNext = 0; // character index within separator to attempt to match next | |
foreach ($astr as $char) { | |
if ($matchNext >= $sepLen) { // full separator has been matched, store and continue | |
$result[] = str_replace($escape . $sep, $sep, $buffer); | |
$buffer = ''; | |
$matchedBuffer = ''; | |
$matchNext = 0; | |
} | |
$nextChar = substr($sep, $matchNext, 1); // get next character to match | |
if ($char == $nextChar && !$wasEsc) { // partial separator match, keep matching | |
$matchNext++; | |
$matchedBuffer .= $char; | |
} else if ($matchNext > 0) { // matched partially but not completely, add matched chars to buffer | |
$buffer .= $matchedBuffer; | |
$matchNext = 0; | |
} else { | |
$buffer .= $char; // this isnt a separator, add to buffer | |
} | |
if ($char == $escape && $matchNext == 0) { // detect escape characters and flag that the next character *cannot* match | |
$wasEsc = true; | |
continue; | |
} | |
$wasEsc = false; // otherwise reset the escape character flag | |
} | |
// add any remaining buffered chars as the last element | |
if ($buffer || $matchedBuffer) { | |
$result[] = str_replace($escape . $sep, $sep, $buffer . $matchedBuffer); | |
} | |
return $result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Maybe I'm not using this the way it is expected but it doesn't seem to work for this scenario:
The expected output is:
And the actual output is: