mb_str_split
Функция вернёт массив строк, это версия str_split() с поддержкой кодировок переменного размера символов, а также кодировок фиксированного размера из 1, 2 или 4-байтовых символов. Если указан параметр length , строка разбивается на куски указанной длины в символах (не байтах). Может быть указан необязательный параметр encoding , это хорошая практика.
Список параметров
Строка ( string ) для разделения на символы или куски.
Если указано, каждый элемент возвращаемого массива будет состоять из нескольких символов вместо одного символа.
Параметр encoding представляет собой символьную кодировку. Если он опущен или равен null , вместо него будет использовано значение внутренней кодировки.
Строка, указывающая одну из поддерживаемых кодировок.
Возвращаемые значения
mb_str_split() возвращает массив строк.
Список изменений
| Версия | Описание |
|---|---|
| 8.0.0 | Теперь параметр encoding может принимать значение null . |
| 8.0.0 | Функция больше не возвращает false в случае неудачи. |
Смотрите также
- str_split() — Преобразует строку в массив
User Contributed Notes 3 notes
1 year ago
if( !function_exists(‘mb_str_split’)) <
function mb_str_split( $string = », $length = 1 , $encoding = null ) <
if(!empty($string)) <
$split = array();
$mb_strlen = mb_strlen($string,$encoding);
for($pi = 0; $pi < $mb_strlen; $pi += $length)<
$substr = mb_substr($string, $pi,$length,$encoding);
if( !empty($substr)) <
$split[] = $substr;
>
>
>
return $split;
>
>
3 years ago
Note: function return NULL if can’t convert argument type.
if (! in_array ( $encoding , mb_list_encodings (), true )) static $aliases ;
if ( $aliases === null ) $aliases = [];
foreach ( mb_list_encodings () as $encoding ) $encoding_aliases = mb_encoding_aliases ( $encoding );
if ( $encoding_aliases ) foreach ( $encoding_aliases as $alias ) $aliases [] = $alias ;
>
>
>
>
if (! in_array ( $encoding , $aliases , true )) trigger_error ( ‘mb_str_split(): Unknown encoding «‘ . $encoding . ‘»‘ , E_USER_WARNING );
return null ;
>
>
$result = [];
$length = mb_strlen ( $string , $encoding );
for ( $i = 0 ; $i < $length ; $i += $split_length ) $result [] = mb_substr ( $string , $i , $split_length , $encoding );
>
return $result ;
>
?>
3 years ago
Lazy polyfill for UTF-8 only:
function utf8_str_split(string $input, int $splitLength = 1)
$re = \sprintf(‘/\\G.+/us’, $splitLength);
\preg_match_all($re, $input, $m);
return $m[0];
>
- Функции для работы с многобайтовыми строками
- mb_check_encoding
- mb_chr
- mb_convert_case
- mb_convert_encoding
- mb_convert_kana
- mb_convert_variables
- mb_decode_mimeheader
- mb_decode_numericentity
- mb_detect_encoding
- mb_detect_order
- mb_encode_mimeheader
- mb_encode_numericentity
- mb_encoding_aliases
- mb_ereg_match
- mb_ereg_replace_callback
- mb_ereg_replace
- mb_ereg_search_getpos
- mb_ereg_search_getregs
- mb_ereg_search_init
- mb_ereg_search_pos
- mb_ereg_search_regs
- mb_ereg_search_setpos
- mb_ereg_search
- mb_ereg
- mb_eregi_replace
- mb_eregi
- mb_get_info
- mb_http_input
- mb_http_output
- mb_internal_encoding
- mb_language
- mb_list_encodings
- mb_ord
- mb_output_handler
- mb_parse_str
- mb_preferred_mime_name
- mb_regex_encoding
- mb_regex_set_options
- mb_scrub
- mb_send_mail
- mb_split
- mb_str_pad
- mb_str_split
- mb_strcut
- mb_strimwidth
- mb_stripos
- mb_stristr
- mb_strlen
- mb_strpos
- mb_strrchr
- mb_strrichr
- mb_strripos
- mb_strrpos
- mb_strstr
- mb_strtolower
- mb_strtoupper
- mb_strwidth
- mb_substitute_character
- mb_substr_count
- mb_substr
- Copyright © 2001-2023 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
explode
Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string separator .
Parameters
The boundary string.
The input string.
If limit is set and positive, the returned array will contain a maximum of limit elements with the last element containing the rest of string .
If the limit parameter is negative, all components except the last — limit are returned.
If the limit parameter is zero, then this is treated as 1.
Note:
Prior to PHP 8.0, implode() accepted its parameters in either order. explode() has never supported this: you must ensure that the separator argument comes before the string argument.
Return Values
Returns an array of string s created by splitting the string parameter on boundaries formed by the separator .
If separator is an empty string («»), explode() throws a ValueError . If separator contains a value that is not contained in string and a negative limit is used, then an empty array will be returned, otherwise an array containing string will be returned. If separator values appear at the start or end of string , said values will be added as an empty array value either in the first or last position of the returned array respectively.
Changelog
Version Description 8.0.0 explode() will now throw ValueError when separator parameter is given an empty string ( «» ). Previously, explode() returned false instead. Examples
Example #1 explode() examples
// Example 1
$pizza = «piece1 piece2 piece3 piece4 piece5 piece6» ;
$pieces = explode ( » » , $pizza );
echo $pieces [ 0 ]; // piece1
echo $pieces [ 1 ]; // piece2?php
// Example 2
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell ) = explode ( «:» , $data );
echo $user ; // foo
echo $pass ; // *Example #2 explode() return examples
/*
A string that doesn’t contain the delimiter will simply
return a one-length array of the original string.
*/
$input1 = «hello» ;
$input2 = «hello,there» ;
$input3 = ‘,’ ;
var_dump ( explode ( ‘,’ , $input1 ) );
var_dump ( explode ( ‘,’ , $input2 ) );
var_dump ( explode ( ‘,’ , $input3 ) );?php
The above example will output:
array(1) ( [0] => string(5) "hello" ) array(2) ( [0] => string(5) "hello" [1] => string(5) "there" ) array(2) ( [0] => string(0) "" [1] => string(0) "" )
Example #3 limit parameter examples
// positive limit
print_r ( explode ( ‘|’ , $str , 2 ));// negative limit
print_r ( explode ( ‘|’ , $str , — 1 ));
?>The above example will output:
Array ( [0] => one [1] => two|three|four ) Array ( [0] => one [1] => two [2] => three )
Notes
Note: This function is binary-safe.
See Also
- preg_split() — Split string by a regular expression
- str_split() — Convert a string to an array
- mb_split() — Split multibyte string using regular expression
- str_word_count() — Return information about words used in a string
- strtok() — Tokenize string
- implode() — Join array elements with a string
User Contributed Notes 4 notes
1 year ago
Note that an empty input string will still result in one element in the output array. This is something to remember when you are processing unknown input.
For example, maybe you are splitting part of a URI by forward slashes (like «articles/42/show» => [«articles», «42», «show»]). And maybe you expect that an empty URI will result in an empty array («» => []). Instead, it will contain one element, with an empty string:
$uri = » ;
$parts = explode ( ‘/’ , $uri );
var_dump ( $parts );2 years ago
Be careful, while most non-alphanumeric data types as input strings return an array with an empty string when used with a valid separator, true returns an array with the string «1»!
var_dump(explode(‘,’, null)); //array(1) < [0]=>string(0) «» >
var_dump(explode(‘,’, false)); //array(1) < [0]=>string(0) «» >var_dump(explode(‘,’, true)); //array(1) < [0]=>string(1) «1» >
10 days ago
If your data is smaller than the expected count with the list expansion:
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell , $nu ) = explode ( «:» , $data );
?>The result is a warning not an error:
PHP Warning: Undefined array key 7 in .
The solution is to pad the array to the expected length:
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell , $nu ) = array_pad ( explode ( «:» , $data ), 8 , «» );
// where 8 is the count of the list arguments
?>1 year ago
If you want to directly take a specific value without having to store it in another variable, you can implement the following:
echo $status_only = explode(‘-‘, $status)[0];
- Copyright © 2001-2023 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
preg_split
Если указан, функция возвращает не более, чем limit подстрок. Оставшаяся часть строки будет возвращена в последней подстроке. Специальное значение limit , равное -1 или 0, подразумевает отсутствие ограничения.
flags может быть любой комбинацией следующих флагов (объединённых с помощью побитового оператора | ): PREG_SPLIT_NO_EMPTY Если указан этот флаг, функция preg_split() вернёт только непустые подстроки. PREG_SPLIT_DELIM_CAPTURE Если указан этот флаг, выражение, заключённое в круглые скобки в разделяющем шаблоне, также извлекается из заданной строки и возвращается функцией. PREG_SPLIT_OFFSET_CAPTURE
Если указан этот флаг, для каждой найденной подстроки будет указана её позиция в исходной строке. Необходимо помнить, что этот флаг меняет формат возвращаемого массива: каждый элемент будет содержать массив, содержащий в индексе с номером 0 найденную подстроку, а смещение этой подстроки в параметре subject — в индексе 1 .
Возвращаемые значения
Возвращает массив, состоящий из подстрок заданной строки subject , которая разбита по границам, соответствующим шаблону pattern или false в случае возникновения ошибки.
Ошибки
Если переданный шаблон регулярного выражения не компилируется в допустимое регулярное выражение, выдаётся ошибка уровня E_WARNING .
Примеры
Пример #1 preg_split() пример: Получение подстрок из заданного текста
// разбиваем строку по произвольному числу запятых и пробельных символов,
// которые включают в себя » «, \r, \t, \n и \f
$keywords = preg_split ( «/[\s,]+/» , «hypertext language, programming» );
print_r ( $keywords );
?>?phpРезультат выполнения данного примера:
Array ( [0] => hypertext [1] => language [2] => programming )
Пример #2 Разбиваем строку на составляющие символы
$str = ‘string’ ;
$chars = preg_split ( ‘//’ , $str , — 1 , PREG_SPLIT_NO_EMPTY );
print_r ( $chars );
?>?phpРезультат выполнения данного примера:
Array ( [0] => s [1] => t [2] => r [3] => i [4] => n [5] => g )
Пример #3 Разбиваем строку с указанием смещения для каждой из найденных подстрок
$str = ‘hypertext language programming’ ;
$chars = preg_split ( ‘/ /’ , $str , — 1 , PREG_SPLIT_OFFSET_CAPTURE );
print_r ( $chars );
?>?phpРезультат выполнения данного примера:
Array ( [0] => Array ( [0] => hypertext [1] => 0 ) [1] => Array ( [0] => language [1] => 10 ) [2] => Array ( [0] => programming [1] => 19 ) )
Примечания
Подсказка
Если вам не нужна мощь регулярных выражений, вы можете выбрать более быстрые (хоть и простые) альтернативы наподобие explode() или str_split() .
Подсказка
Если соответствий не нашлось, то возвращается массив с единственным элементом равным всей строке.
Смотрите также
- «Регулярные выражения PCRE»
- preg_quote() — Экранирует символы в регулярных выражениях
- implode() — Объединяет элементы массива в строку
- preg_match() — Выполняет проверку на соответствие регулярному выражению
- preg_match_all() — Выполняет глобальный поиск шаблона в строке
- preg_replace() — Выполняет поиск и замену по регулярному выражению
- preg_last_error() — Возвращает код ошибки выполнения последнего регулярного выражения PCRE
User Contributed Notes 18 notes
14 years ago
Sometimes PREG_SPLIT_DELIM_CAPTURE does strange results.
$content = ‘Lorem ipsum dolor sit amet consectetuer.’ ;
$chars = preg_split ( ‘/<[^>]*[^\/]>/i’ , $content , — 1 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
print_r ( $chars );
?>
Produces:
Array
(
[0] => Lorem ipsum dolor
[1] => sit amet
[2] => consec
[3] => tet
[4] => uer
)So that the delimiter patterns are missing. If you wanna get these patters remember to use parentheses.
$chars = preg_split ( ‘/(<[^>]*[^\/]>)/i’ , $content , — 1 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
print_r ( $chars ); //parentheses added
?>
Produces:
Array
(
[0] =>
[1] => Lorem ipsum dolor
[2] =>
[3] => sit amet
[4] =>
[5] => consec
[6] =>
[7] => tet
[8] =>
[9] => uer
[10] =>
[11] => .
)14 years ago
Extending m.timmermans’s solution, you can use the following code as a search expression parser:
$search_expression = «apple bear \»Tom Cruise\» or ‘Mickey Mouse’ another word» ;
$words = preg_split ( «/[\s,]*\\\»([^\\\»]+)\\\»[\s,]*|» . «[\s,]*'([^’]+)'[\s,]*|» . «[\s,]+/» , $search_expression , 0 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
print_r ( $words );
?>The result will be:
Array
(
[0] => apple
[1] => bear
[2] => Tom Cruise
[3] => or
[4] => Mickey Mouse
[5] => another
[6] => word
)1. Accepted delimiters: white spaces (space, tab, new line etc.) and commas.
2. You can use either simple (‘) or double («) quotes for expressions which contains more than one word.
8 years ago
This regular expression will split a long string of words into an array of sub-strings, of some maximum length, but only on word-boundries.
I use the reg-ex with preg_match_all(); but, I’m posting this example here (on the page for preg_split()) because that’s where I looked when I wanted to find a way to do this.
Hope it saves someone some time.
// example of a long string of words
$long_string = ‘Your IP Address will be logged with the submitted note and made public on the PHP manual user notes mailing list. The IP address is logged as part of the notes moderation process, and won\’t be shown within the PHP manual itself.’ ;// «word-wrap» at, for example, 60 characters or less
$max_len = 60 ;// this regular expression will split $long_string on any sub-string of
// 1-or-more non-word characters (spaces or punctuation)
if( preg_match_all ( «/. >(?=\W+)/» , $long_string , $lines ) !== False )// $lines now contains an array of sub-strings, each will be approx.
// $max_len characters — depending on where the last word ended and
// the number of ‘non-word’ characters found after the last word
for ( $i = 0 ; $i < count ( $lines [ 0 ]); $i ++) echo "[ $i ] < $lines [ 0 ][ $i ]>\n» ;
>
>
?>4 years ago
Assuming you’re using UTF-8, this function can be used to separate Unicode text into individual codepoints without the need for the multibyte extension.
preg_split ( ‘//u’ , $text , — 1 , PREG_SPLIT_NO_EMPTY );
?>
The words «English», «Español», and «Русский» are all seven letters long. But strlen would report string lengths 7, 8 and 14, respectively. The preg_split above would return a seven-element array in all three cases.
It splits ‘한국어’ into the array [‘한’, ‘국’, ‘어’] instead of the 9-character array that str_split($text) would produce.
12 years ago
Here is another way to split a CamelCase string, which is a simpler expression than the one using lookaheads and lookbehinds:
preg_split(‘/([[:upper:]][[:lower:]]+)/’, $last, null, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY)
It makes the entire CamelCased word the delimiter, then returns the delimiters (PREG_SPLIT_DELIM_CAPTURE) and omits the empty values between the delimiters (PREG_SPLIT_NO_EMPTY)
13 years ago
If you want to split by a char, but want to ignore that char in case it is escaped, use a lookbehind assertion.
In this example a string will be split by «:» but «\:» will be ignored:
19 years ago
To clarify the «limit» parameter and the PREG_SPLIT_DELIM_CAPTURE option,
$preg_split ( ‘(/ /)’ , ‘1 2 3 4 5 6 7 8’ , 4 , PREG_SPLIT_DELIM_CAPTURE );
?>returns:
(‘1’, ‘ ‘, ‘2’, ‘ ‘ , ‘3’, ‘ ‘, ‘4 5 6 7 8’)
So you actually get 7 array items not 4
18 years ago
preg_split() behaves differently from perl’s split() if the string ends with a delimiter. This perl snippet will print 5:
my @a = split(/ /, «a b c d e «);
print scalar @a;The corresponding php code prints 6:
This is not necessarily a bug (nowhere does the documentation say that preg_split() behaves the same as perl’s split()) but it might surprise perl programmers.
12 years ago
You must be caution when using lookbehind to a variable match.
For example:
‘/(? to match a new line when not \ is before it don’t go as spected as it match \r as the lookbehind (becouse isn’t a \) and is optional before \n.You must use this for example:
‘/((?That match a alone \n (not preceded by \r or \) or a \r\n not preceded by a \.2 years ago
Beware that it is not safe to assume there are no empty values returned by PREG_SPLIT_NO_EMPTY, nor that you will see no delimiters if you use PREG_SPLIT_DELIM_CAPTURE, as there are some edge cases where these are not true.
# As expected, splitting a string by itself returns two empty strings:
var_export ( preg_split ( «/x/» , «x» ));# But if we add PREG_SPLIT_NO_EMPTY, then instead of an empty array, we get the delimiter.
var_export ( preg_split ( «/x/» , «x» , PREG_SPLIT_NO_EMPTY ));And if we try to split an empty string , then instead of an empty array, we get an empty string even with PREG_SPLIT_NO_EMPTY .
var_export ( preg_split ( «/x/» , «» , PREG_SPLIT_NO_EMPTY ));9 years ago
This is a function to truncate a string of text while preserving the whitespace (for instance, getting an excerpt from an article while maintaining newlines). It will not jive well with HTML, of course.
/**
* Truncates a string of text by word count
* @param string $text The text to truncate
* @param int $max_words The maximum number of words
* @return string The truncated text
*/
function limit_words ( $text , $max_words ) $split = preg_split ( ‘/(\s+)/’ , $text , — 1 , PREG_SPLIT_DELIM_CAPTURE );
$truncated = » ;
for ( $i = 0 ; $i < min ( count ( $split ), $max_words * 2 ); $i += 2 ) $truncated .= $split [ $i ]. $split [ $i + 1 ];
>
return trim ( $truncated );
>
?>14 years ago
To split a camel-cased string using preg_split() with lookaheads and lookbehinds:
14 years ago
If the task is too complicated for preg_split, preg_match_all might come in handy, since preg_split is essentially a special case.
I wanted to split a string on a certain character (asterisk), but only if it wasn’t escaped (by a preceding backslash). Thus, I should ensure an even number of backslashes before any asterisk meant as a splitter. Look-behind in a regular expression wouldn’t work since the length of the preceding backslash sequence can’t be fixed. So I turned to preg_match_all:
// split a string at unescaped asterisks
// where backslash is the escape character
$splitter = «/\\*((?:[^\\\\*]|\\\\.)*)/» ;
preg_match_all ( $splitter , «* $string » , $aPieces , PREG_PATTERN_ORDER );
$aPieces = $aPieces [ 1 ];// $aPieces now contains the exploded string
// and unescaping can be safely done on each piece
foreach ( $aPieces as $idx => $piece )
$aPieces [ $idx ] = preg_replace ( «/\\\\(.)/s» , «$1» , $piece );
?>12 years ago
Limit = 1 may be confusing. The important thing is that in case of limit equals to 1 will produce only ONE substring. Ergo the only one substring will be the first one as well as the last one. Tnat the rest of the string (after the first delimiter) will be placed to the last substring. But last is the first and only one.
$output = $preg_split ( ‘(/ /)’ , ‘1 2 3 4 5 6 7 8’ , 1 );
echo $output [ 0 ] //will return whole string!;
$output = $preg_split ( ‘(/ /)’ , ‘1 2 3 4 5 6 7 8’ , 2 );
echo $output [ 0 ] //will return 1;
echo $output [ 1 ] //will return ‘2 3 4 5 6 7 8’;strtok
Альтернативная сигнатура (не поддерживается с именованными аргументами):
strtok ( string $token ): string | false
strtok() разбивает строку string на подстроки (токены), используя в качестве разделителей символы из token . Например, строку «This is an example string» можно разбить на отдельные слова, используя пробел в качестве разделителя ( token ).
Заметьте, что исходная строка ( string ) передаётся только при первом вызове этой функции. Последующим вызовам передаются только разделители ( token ), так как эта функция сохраняет исходную строку и запоминает позицию в этой строке между вызовами. Для работы с новой строкой ( string ) нужно снова вызвать функцию с двумя аргументами. Обратите внимание, что в параметре token можно использовать несколько разделителей. Строка будет делиться по любому найденному символу, присутствующему в параметре ( token ).
Замечание:
Функция ведёт себя немного иначе, чем можно было бы ожидать, знакомясь с explode() . Во-первых, последовательность из двух или более смежных символов token в анализируемой строке считается одним разделителем. Также игнорируется token , расположенный в начале или конце строки. Например, если используется строка «;aaa;;bbb;» , последовательные вызовы strtok() с «;» в качестве token вернут строки «aaa» и «bbb», а затем false . В результате строка будет разделена только на два элемента, а explode(«;», $string) вернёт массив из 5 элементов.
Список параметров
Строка ( string ), разбиваемая на подстроки (токены).
Разделитель строки string .
Возвращаемые значения
Токен в виде строки ( string ) или false , если токенов больше нет.
Примеры
Пример #1 Пример использования strtok()
$string = «This is\tan example\nstring» ;
/* В качестве разделителей используем пробел, табуляцию и перевод строки */
$tok = strtok ( $string , » \n\t» );?php
while ( $tok !== false ) echo «Word= $tok
» ;
$tok = strtok ( » \n\t» );
>
?>Пример #2 Способ обработки пустых подстрок функцией strtok()
$first_token = strtok ( ‘/something’ , ‘/’ );
$second_token = strtok ( ‘/’ );
var_dump ( $first_token , $second_token );
?>?phpРезультат выполнения данного примера:
string(9) "something" bool(false)
Пример #3 Различие между strtok() и explode()
$parts = [];
$tok = strtok ( $string , «;» );
while ( $tok !== false ) $parts [] = $tok ;
$tok = strtok ( «;» );
>
echo json_encode ( $parts ), «\n» ;$parts = explode ( «;» , $string );
echo json_encode ( $parts ), «\n» ;Результат выполнения данного примера:
["aaa","bbb"] ["","aaa","","bbb",""]
Примечания
Внимание
Эта функция может возвращать как логическое значение false , так и значение не типа boolean, которое приводится к false . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.
Смотрите также
- explode() — Разбивает строку с помощью разделителя
User Contributed Notes 20 notes
10 years ago
// strtok example
$str = ‘Hello to all of Ukraine’ ;
echo strtok ( $str , ‘ ‘ ). ‘ ‘ . strtok ( ‘ ‘ ). ‘ ‘ . strtok ( ‘ ‘ );
?>
Result:
Hello to all?php19 years ago
/** get leading, trailing, and embedded separator tokens that were 'skipped'
if for some ungodly reason you are using php to implement a simple parser that
needs to detect nested clauses as it builds a parse tree */$seps = ‘()’ ;
$tok = strtok ( $str , $seps ); // return false on empty string or null
$cur = 0 ;
$dumbDone = FALSE ;
$done = ( FALSE === $tok );
while (! $done ) // process skipped tokens (if any at first iteration) (special for last)
$posTok = $dumbDone ? strlen ( $str ) : strpos ( $str , $tok , $cur );
$skippedMany = substr ( $str , $cur , $posTok — $cur ); // false when 0 width
$lenSkipped = strlen ( $skippedMany ); // 0 when false
if ( 0 !== $lenSkipped ) $last = strlen ( $skippedMany ) — 1 ;
for( $i = 0 ; $i <= $last ; $i ++)$skipped = $skippedMany [ $i ];
$cur += strlen ( $skipped );
echo «skipped: $skipped \n» ;
>
>
if ( $dumbDone ) break; // this is the only place the loop is terminated// process current tok
echo «curr tok: » . $tok . «\n» ;// update cursor
$cur += strlen ( $tok );// get any next tok
if (! $dumbDone ) $tok = strtok ( $seps );
$dumbDone = ( FALSE === $tok );
// you’re not really done till you check for trailing skipped
>
>;
?>12 years ago
If you have memory-usage critical solution, you should keep in mind, that strtok function holds input string parameter (or reference to it?) in memory after usage.
function tokenize ( $str , $token_symbols ) $word = strtok ( $str , $token_symbols );
while ( false !== $word ) // do something here.
$word = strtok ( $token_symbols );
>
>
?>
Test-cases with handling ~10MB plain-text file:
Case #1 — unset $str variable
$token_symbols = » \t\n» ;
$str = file_get_contents ( ’10MB.txt’ ); // mem usage 9.75383758545 MB (memory_get_usage() / 1024 / 1024));
tokenize ( $str , $token_symbols ); // mem usage 9.75400161743 MB
unset( $str ); // 9.75395584106 MB
?>
Case #1 result: memory is still usedCase #2 — call strtok again
$token_symbols = » \t\n» ;
$str = file_get_contents ( ’10MB.txt’ ); // 9.75401306152 MB
tokenize ( $str , $token_symbols ); // 9.75417709351
strtok ( » , » ); // 9.75421524048
?>
Case #2 result: memory is still usedCase #3 — call strtok again AND unset $str variable
$token_symbols = » \t\n» ;
$str = file_get_contents ( ’10MB.txt’ ); // 9.75410079956 MB
tokenize ( $str , $token_symbols ); // 9.75426483154 MB
unset( $str );
strtok ( » , » ); // 0.0543975830078 MB
?>
Case #3 result: memory is freeSo, better solution for tokenize function:
function tokenize ( $str , $token_symbols , $token_reset = true ) $word = strtok ( $str , $token_symbols );
while ( false !== $word ) // do something here.
$word = strtok ( $token_symbols );
>8 years ago
14 years agoSimple way to tokenize search parameters, including double or single quoted keys. If only one quote is found, the rest of the string is assumed to be part of that token.
$token = strtok ( $keywords , ‘ ‘ );
while ( $token ) <
// find double quoted tokens
if ( $token < 0 >== ‘»‘ ) < $token .= ' ' . strtok ( '"' ). '"' ; >
// find single quoted tokens
if ( $token < 0 >== «‘» )$tokens [] = $token ;
$token = strtok ( ‘ ‘ );
>
?>Use substr(1,strlen($token)) and remove the part that adds the trailing quotes if you want your output without quotes.
14 years ago
This looks very simple, but it took me a long time to figure out so I thought I’d share it incase someone else was wanting the same thing:
this should work similar to substr() but with tokens instead!
/* subtok(string,chr,pos,len)
*
* chr = chr used to seperate tokens
* pos = starting postion
* len = length, if negative count back from right
*
* subtok(‘a.b.c.d.e’,’.’,0) = ‘a.b.c.d.e’
* subtok(‘a.b.c.d.e’,’.’,0,2) = ‘a.b’
* subtok(‘a.b.c.d.e’,’.’,2,1) = ‘c’
* subtok(‘a.b.c.d.e’,’.’,2,-1) = ‘c.d’
* subtok(‘a.b.c.d.e’,’.’,-4) = ‘b.c.d.e’
* subtok(‘a.b.c.d.e’,’.’,-4,2) = ‘b.c’
* subtok(‘a.b.c.d.e’,’.’,-4,-1) = ‘b.c.d’
*/
function subtok ( $string , $chr , $pos , $len = NULL ) return implode ( $chr , array_slice ( explode ( $chr , $string ), $pos , $len ));
>
?>explode breaks the tokens up into an array, array slice alows you to pick then tokens you want, and then implode converts it back to a string
although its far from a clone, this was inspired by mIRC’s gettok() function
9 years ago
Might be pointing out the obvious but if you’d rather use a for loop rather than a while (to keep the token strings on the same line for readability for example), it can be done. Added bonus, it doesn’t put a $tok variable outside the loop itself either.
Downside however is that you’re not able to manually free up the memory used using the technique mentioned by elarlang.for( $tok = strtok ( $str , ‘ _-.’ ); $tok !== false ; $tok = strtok ( ‘ _-.’ ))
echo » $tok » ;
>
?>9 years ago
If you want to tokenize by only one letter, explode() is much faster compared to strtok().
$str = str_repeat ( ‘foo ‘ , 10000 );
//explode()
$time = microtime ( TRUE );
$arr = explode ( $str , ‘ ‘ );
$time = microtime ( TRUE )- $time ;
echo «explode(): $time sec.» . PHP_EOL ;//strtok()
$time = microtime ( TRUE );
$ret = strtok ( ‘ ‘ , $str );
while( $ret !== FALSE ) $ret = strtok ( ‘ ‘ );
>
$time = microtime ( TRUE )- $time ;
echo «strtok(): $time sec.» . PHP_EOL ;?>
The result is : (PHP 5.3.3 on CentOS)
explode():0.001317024230957 sec.
strtok():0.0058917999267578 sec.explode() is about five times fast in short strings, too.
11 years ago
Note that strtok may receive different tokens each time. Therefore, if, for example, you wish to extract several words and then the rest of the sentence:
$text = «13 202 5 This is a long message explaining the error codes.» ;
$error1 = strtok ( $text , » » ); //13
$error2 = strtok ( » » ); //202
$error3 = strtok ( » » ); //5
$error_message = strtok ( «» ); //Notice the different token parameter
echo $error_message ; //This is a long message explaining the error codes.
?>14 years ago
As of the change in strtok()’s handling of empty strings, it is now useless for scripts that rely on empty data to function.
Take for instance, a standard header. (with UNIX newlines)
http/1.0 200 OK\n
Content-Type: text/html\n
\n
—HTML BODY HERE—When parsing this with strtok, one would wait until it found an empty string to signal the end of the header. However, because strtok now skips empty segments, it is impossible to know when the header has ended.
This should not be called `correct’ behavior, it certainly is not. It has rendered strtok incapable of (properly) processing a very simple standard.This new functionality, however, does not affect Windows style headers. You would search for a line that only contains «\r»
This, however, is not a justification for the change.14 years ago
Here is a java like StringTokenizer class using strtok function:
/**
* The string tokenizer class allows an application to break a string into tokens.
*
* @example The following is one example of the use of the tokenizer. The code:
*
* * $str = 'this is:@\t\n a test!';
* $delim = ' !@:'\t\n; // remove these chars
* $st = new StringTokenizer($str, $delim);
* while ($st->hasMoreTokens()) * echo $st->nextToken() . "\n";
* >
* prints the following output:
* this
* is
* a
* test
* ?>
*
*/
class StringTokenizer/**
* @var string
*/
private $delim ;
/**
* Constructs a string tokenizer for the specified string
* @param string $str String to tokenize
* @param string $delim The set of delimiters (the characters that separate tokens)
* specified at creation time, default to ‘ ‘
*/
public function __construct ( /*string*/ $str , /*string*/ $delim = ‘ ‘ ) $this -> token = strtok ( $str , $delim );
$this -> delim = $delim ;
>public function __destruct () unset( $this );
>/**
* Tests if there are more tokens available from this tokenizer’s string. It
* does not move the internal pointer in any way. To move the internal pointer
* to the next element call nextToken()
* @return boolean — true if has more tokens, false otherwise
*/
public function hasMoreTokens () return ( $this -> token !== false );
>/**
* Returns the next token from this string tokenizer and advances the internal
* pointer by one.
* @return string — next element in the tokenized string
*/
public function nextToken () $current = $this -> token ;
$this -> token = strtok ( $this -> delim );
return $current ;
>
>
?>7 months ago
Hello, portuguese documentation of strtok is wrong, at this part which the example(2) is wrong.
Exemplo #2 Comportamento antigo da strtok()
$first_token = strtok ( ‘/something’ , ‘/’ );
$second_token = strtok ( ‘/’ );
var_dump ( $first_token , $second_token );
?>O exemplo acima produzirá:
string(0) «»
string(9) «something»(this example above, should be inverted as this:)
Correct:
string(9) «something»
string(0) «»(exemple 3 is correct)
Exemplo #3 Novo comportamento da strtok()
$first_token = strtok ( ‘/something’ , ‘/’ );
$second_token = strtok ( ‘/’ );
var_dump ( $first_token , $second_token );
?>O exemplo acima produzirá:
string(9) «something»
bool(false)4 years ago
I found this useful for parsing user entered links in text fields.
2 years ago
After obtaining zero or more tokens with calls to strtok, you can obtain the remainder of the input string by calling strtok with an empty string as the delimiter.
7 years ago
@maisuma you invert paramaters of explode() and strtok() functions, your code does not do what you expect.
You expect to read the input string token after token so equivalent code for strtok() is arra_filter(explode()) because explode() return lines of empty string when several delimiters are contiguous in the read string, for example 2 whitespaces between.In fact strtok() is much faster (x2 at least) than arra_filter(explode()) if the read string contains several contiguous delimiters ,
it is slower if the read string contains one and only one delimiter between tokens.$repeat = 10 ;
$delimiter = ‘:’ ;
$str = str_repeat ( ‘foo:’ , $repeat );$timeStrtok = microtime ( TRUE );
$token = strtok ( $str , $delimiter );
while( $token !== FALSE ) //echo $token . ‘,’;
$token = strtok ( $delimiter );
>
$timeStrtok -= microtime ( TRUE );$timeExplo = microtime ( TRUE );
$arr = explode ( $delimiter , $str );
//$arr = array_filter($arr);
$timeExplo -= microtime ( TRUE );$X = 1000000 ; $unit = ‘microsec’ ;
echo PHP_EOL . ‘ explode() : ‘ . — $timeExplo . ‘ ‘ . $unit . PHP_EOL . ‘ strtok() : ‘ . — $timeStrtok . ‘ ‘ . $unit . PHP_EOL ;
$timeExplo = round (- $timeExplo * $X );
$timeStrtok = round (- $timeStrtok * $X );echo PHP_EOL . ‘ explode() : ‘ . $timeExplo . ‘ ‘ . $unit . PHP_EOL . ‘ strtok() : ‘ . $timeStrtok . ‘ ‘ . $unit . PHP_EOL ;
echo ‘ ratio explode / strtok : ‘ . round ( $timeExplo / $timeStrtok , 1 ) . PHP_EOL ;12 years ago
Here’s a simple class that allows you to iterate through string tokens using a foreach loop.
/**
* The TokenIterator class allows you to iterate through string tokens using
* the familiar foreach control structure.
*
* Example:
*
* * $string = 'This is a test.';
* $delimiters = ' ';
* $ti = new TokenIterator($string, $delimiters);
*
* foreach ($ti as $count => $token) <
* echo sprintf("%d, %s\n", $count, $token);
* >
*
* // Prints the following output:
* // 0. This
* // 1. is
* // 2. a
* // 3. test.
*
*/
class TokenIterator implements Iterator
<
/**
* The string to tokenize.
* @var string
*/
protected $_string ;/**
* The token delimiters.
* @var string
*/
protected $_delims ;/**
* Stores the current token.
* @var mixed
*/
protected $_token ;/**
* Internal token counter.
* @var int
*/
protected $_counter = 0 ;/**
* Constructor.
*
* @param string $string The string to tokenize.
* @param string $delims The token delimiters.
*/
public function __construct ( $string , $delims )
<
$this -> _string = $string ;
$this -> _delims = $delims ;
$this -> _token = strtok ( $string , $delims );
>/**
* @see Iterator::current()
*/
public function current ()
<
return $this -> _token ;
>/**
* @see Iterator::key()
*/
public function key ()
<
return $this -> _counter ;
>/**
* @see Iterator::next()
*/
public function next ()
<
$this -> _token = strtok ( $this -> _delims );if ( $this -> valid ()) <
++ $this -> _counter ;
>
>/**
* @see Iterator::rewind()
*/
public function rewind ()
<
$this -> _counter = 0 ;
$this -> _token = strtok ( $this -> _string , $this -> _delims );
>/**
* @see Iterator::valid()
*/
public function valid ()
<
return $this -> _token !== FALSE ;
>
>
?>9 years ago
17 years agoThis function takes a string and returns an array with words (delimited by spaces), also taking into account quotes, doublequotes, backticks and backslashes (for escaping stuff).
So$string = «cp ‘my file’ to `Judy’s file`»;
var_dump(parse_cli($string));Way it works, runs through the string character by character, for each character looking up the action to take, based on that character and its current $state.
Actions can be (one or more of) adding the character/string to the current word, adding the word to the output array, and changing or (re)storing the state.
For example a space will become part of the current ‘word’ (or ‘token’) if $state is ‘doublequoted’, but it will start a new token if $state was ‘unquoted’.
I was later told it’s a «tokeniser using a finite state automaton». Who knew 🙂#_____________________
# parse_cli($string) /
function parse_cli ( $string ) $state = ‘space’ ;
$previous = » ; // stores current state when encountering a backslash (which changes $state to ‘escaped’, but has to fall back into the previous $state afterwards)
$out = array(); // the return value
$word = » ;
$type = » ; // type of character
// array[states][chartypes] => actions
$chart = array(
‘space’ => array( ‘space’ => » , ‘quote’ => ‘q’ , ‘doublequote’ => ‘d’ , ‘backtick’ => ‘b’ , ‘backslash’ => ‘ue’ , ‘other’ => ‘ua’ ),
‘unquoted’ => array( ‘space’ => ‘w ‘ , ‘quote’ => ‘a’ , ‘doublequote’ => ‘a’ , ‘backtick’ => ‘a’ , ‘backslash’ => ‘e’ , ‘other’ => ‘a’ ),
‘quoted’ => array( ‘space’ => ‘a’ , ‘quote’ => ‘w ‘ , ‘doublequote’ => ‘a’ , ‘backtick’ => ‘a’ , ‘backslash’ => ‘e’ , ‘other’ => ‘a’ ),
‘doublequoted’ => array( ‘space’ => ‘a’ , ‘quote’ => ‘a’ , ‘doublequote’ => ‘w ‘ , ‘backtick’ => ‘a’ , ‘backslash’ => ‘e’ , ‘other’ => ‘a’ ),
‘backticked’ => array( ‘space’ => ‘a’ , ‘quote’ => ‘a’ , ‘doublequote’ => ‘a’ , ‘backtick’ => ‘w ‘ , ‘backslash’ => ‘e’ , ‘other’ => ‘a’ ),
‘escaped’ => array( ‘space’ => ‘ap’ , ‘quote’ => ‘ap’ , ‘doublequote’ => ‘ap’ , ‘backtick’ => ‘ap’ , ‘backslash’ => ‘ap’ , ‘other’ => ‘ap’ ));
for ( $i = 0 ; $i <= strlen ( $string ); $i ++) $char = substr ( $string , $i , 1 );
$type = array_search ( $char , array( ‘space’ => ‘ ‘ , ‘quote’ => ‘\» , ‘doublequote’ => ‘»‘ , ‘backtick’ => ‘`’ , ‘backslash’ => ‘\\’ ));
if (! $type ) $type = ‘other’ ;
if ( $type == ‘other’ ) // grabs all characters that are also ‘other’ following the current one in one go
preg_match ( «/[ \’\»\`\\\]/» , $string , $matches , PREG_OFFSET_CAPTURE , $i );
if ( $matches ) $matches = $matches [ 0 ];
$char = substr ( $string , $i , $matches [ 1 ]- $i ); // yep, $char length can be > 1
$i = $matches [ 1 ] — 1 ;
>else // no more match on special characters, that must mean this is the last word!
// the .= hereunder is because we *might* be in the middle of a word that just contained special chars
$word .= substr ( $string , $i );
break; // jumps out of the for() loop
>
>
$actions = $chart [ $state ][ $type ];
for( $j = 0 ; $j < strlen ( $actions ); $j ++) $act = substr ( $actions , $j , 1 );
if ( $act == ‘ ‘ ) $state = ‘space’ ;
if ( $act == ‘u’ ) $state = ‘unquoted’ ;
if ( $act == ‘q’ ) $state = ‘quoted’ ;
if ( $act == ‘d’ ) $state = ‘doublequoted’ ;
if ( $act == ‘b’ ) $state = ‘backticked’ ;
if ( $act == ‘e’ ) < $previous = $state ; $state = 'escaped' ; >
if ( $act == ‘a’ ) $word .= $char ;
if ( $act == ‘w’ ) < $out [] = $word ; $word = '' ; >
if ( $act == ‘p’ ) $state = $previous ;
>
>
if ( strlen ( $word )) $out [] = $word ;
return $out ;
>
