49 if ( $newPHP ===
null ) {
50 $newPHP = !mb_check_encoding(
"\xf4\x90\x80\x80",
'UTF-8' );
53 return mb_check_encoding(
$value,
'UTF-8' ) &&
54 ( $newPHP || preg_match(
"/\xf4[\x90-\xbf]|[\xf5-\xff]/S",
$value ) === 0 );
69 $subject, $nested =
false ) {
73 $encStart = preg_quote( $startDelim,
'!' );
74 $encEnd = preg_quote( $endDelim,
'!' );
75 $encSep = preg_quote( $separator,
'!' );
76 $len = strlen( $subject );
82 "!$encStart|$encEnd|$encSep!S", $subject, $m,
83 PREG_OFFSET_CAPTURE, $inputPos
88 $inputPos = $matchPos + strlen( $match );
89 if ( $match === $separator ) {
92 $subject, $lastPos, $matchPos - $lastPos
96 } elseif ( $match === $startDelim ) {
97 if ( $depth === 0 || $nested ) {
104 $exploded[] = substr( $subject, $lastPos );
107 return new ArrayIterator( $exploded );
128 $segments =
explode( $startDelim, $subject );
129 $output = array_shift( $segments );
130 foreach ( $segments
as $s ) {
131 $endDelimPos = strpos(
$s, $endDelim );
132 if ( $endDelimPos ===
false ) {
135 $output .= $replace . substr(
$s, $endDelimPos + strlen( $endDelim ) );
174 $encStart = preg_quote( $startDelim,
'!' );
175 $encEnd = preg_quote( $endDelim,
'!' );
176 $strcmp = strpos(
$flags,
'i' ) ===
false ?
'strcmp' :
'strcasecmp';
177 $endLength = strlen( $endDelim );
180 while ( $inputPos < strlen( $subject ) &&
181 preg_match(
"!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos )
183 $tokenOffset = $m[0][1];
184 if ( $m[1][0] !=
'' ) {
186 $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0
188 # An end match is present at the same location
190 $tokenLength = $endLength;
192 $tokenType =
'start';
193 $tokenLength = strlen( $m[0][0] );
195 } elseif ( $m[2][0] !=
'' ) {
197 $tokenLength = strlen( $m[0][0] );
199 throw new InvalidArgumentException(
'Invalid delimiter given to ' . __METHOD__ );
202 if ( $tokenType ==
'start' ) {
203 # Only move the start position if we haven't already found a start
204 # This means that START START END matches outer pair
205 if ( !$foundStart ) {
207 $inputPos = $tokenOffset + $tokenLength;
208 # Write out the non-matching section
209 $output .= substr( $subject, $outputPos, $tokenOffset - $outputPos );
210 $outputPos = $tokenOffset;
211 $contentPos = $inputPos;
214 # Move the input position past the *first character* of START,
215 # to protect against missing END when it overlaps with START
216 $inputPos = $tokenOffset + 1;
218 } elseif ( $tokenType ==
'end' ) {
221 $output .= call_user_func( $callback, [
222 substr( $subject, $outputPos, $tokenOffset + $tokenLength - $outputPos ),
223 substr( $subject, $contentPos, $tokenOffset - $contentPos )
227 # Non-matching end, write it out
228 $output .= substr( $subject, $inputPos, $tokenOffset + $tokenLength - $outputPos );
230 $inputPos = $outputPos = $tokenOffset + $tokenLength;
232 throw new InvalidArgumentException(
'Invalid delimiter given to ' . __METHOD__ );
235 if ( $outputPos < strlen( $subject ) ) {
236 $output .= substr( $subject, $outputPos );
261 $replacer->cb(), $subject,
$flags );
272 $placeholder =
"\x00";
275 $text = str_replace( $placeholder,
'', $text );
282 $items =
explode( $separator, $cleaned );
283 foreach ( $items
as $i => $str ) {
284 $items[$i] = str_replace( $placeholder, $separator, $str );
299 $placeholder =
"\x00";
302 $text = str_replace( $placeholder,
'', $text );
309 $cleaned = str_replace( $search, $replace, $cleaned );
310 $text = str_replace( $placeholder, $search, $cleaned );
323 $string = str_replace(
'\\',
'\\\\', $string );
324 $string = str_replace(
'$',
'\\$', $string );
335 static function explode( $separator, $subject ) {
336 if ( substr_count( $subject, $separator ) > 1000 ) {
339 return new ArrayIterator(
explode( $separator, $subject ) );