<?php
// strtok 例子
$str = 'Hello to all of Ukraine';
echo strtok($str, ' ').' '.strtok(' ').' '.strtok(' ');
?>
结果
Hello to all
(PHP 4, PHP 5, PHP 7, PHP 8)
strtok — 将字符串分解为标记
备用签名(不支持命名参数)
strtok() 将字符串 (string
) 分解成较小的字符串(标记),每个标记由 token
中的任何字符分隔。也就是说,如果您有一个像 "This is an example string" 这样的字符串,您可以使用空格字符作为 token
将此字符串分解成各个单词。
请注意,只有第一次调用 strtok 使用 string
参数。后续每次调用 strtok 只需要使用 token
,因为它会跟踪它在当前字符串中的位置。要重新开始,或对新字符串进行标记,只需再次调用 strtok 并传入 string
参数来初始化它。请注意,您可以在 token
参数中放入多个标记。当找到 token
参数中的任何一个字符时,字符串将被标记化。
注意:
此函数的行为与熟悉 explode() 的人可能期望的略有不同。首先,解析字符串中两个或多个连续的
token
字符被视为单个分隔符。此外,位于字符串开头或结尾的token
将被忽略。例如,如果使用字符串";aaa;;bbb;"
,则连续调用 strtok() 并将";"
作为token
将返回字符串 "aaa" 和 "bbb",然后是false
。因此,字符串将只被分成两个元素,而explode(";", $string)
将返回一个包含 5 个元素的数组。
范例 #1 strtok() 例子
<?php
$string = "This is\tan example\nstring";
/* 使用制表符和换行符作为标记化字符 */
$tok = strtok($string, " \n\t");
while ($tok !== false) {
echo "Word=$tok<br />";
$tok = strtok(" \n\t");
}
?>
范例 #2 strtok() 在找到空部分时的行为
<?php
$first_token = strtok('/something', '/');
$second_token = strtok('/');
var_dump($first_token, $second_token);
?>
上面的例子将输出
string(9) "something" bool(false)
范例 #3 strtok() 和 explode() 之间的区别
<?php
$string = ";aaa;;bbb;";
$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",""]
<?php
// strtok 例子
$str = 'Hello to all of Ukraine';
echo strtok($str, ' ').' '.strtok(' ').' '.strtok(' ');
?>
结果
Hello to all
<pre><?php
/** 获取前导、后缀和嵌入式分隔符标记,这些标记在您使用 php 实现一个简单的解析器时被“跳过”
需要在构建解析树时检测嵌套子句 */
$str = "(((alpha(beta))(gamma))";
$seps = '()';
$tok = strtok( $str,$seps ); // 在空字符串或 null 上返回 false
$cur = 0;
$dumbDone = FALSE;
$done = (FALSE===$tok);
while (!$done) {
// 处理跳过的标记(如果有的话,在第一次迭代时)(最后一次迭代时特殊处理)
$posTok = $dumbDone ? strlen($str) : strpos($str, $tok, $cur );
$skippedMany = substr( $str, $cur, $posTok-$cur ); // 当宽度为 0 时为 false
$lenSkipped = strlen($skippedMany); // 当为 false 时为 0
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; // 这是循环终止的唯一地方
// 处理当前标记
echo "curr tok: ".$tok."\n";
// 更新游标
$cur += strlen($tok);
// 获取下一个标记
if (!$dumbDone){
$tok = strtok($seps);
$dumbDone = (FALSE===$tok);
// 直到检查了尾部跳过的标记,才算真正完成
}
};
?></pre>
如果你有内存使用量很重要的解决方案,你应该记住,strtok 函数在使用后会将输入字符串参数(或指向它的引用?)保存在内存中。
<?php
function tokenize($str, $token_symbols) {
$word = strtok($str, $token_symbols);
while (false !== $word) {
// 在这里做一些事情...
$word = strtok($token_symbols);
}
}
?>
测试用例,处理约 10MB 纯文本文件
案例 #1 - unset $str 变量
<?php
$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // 内存使用量 9.75383758545 MB (memory_get_usage() / 1024 / 1024));
tokenize($str, $token_symbols); // 内存使用量 9.75400161743 MB
unset($str); // 9.75395584106 MB
?>
案例 #1 结果:内存仍在使用中
案例 #2 - 再次调用 strtok
<?php
$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // 9.75401306152 MB
tokenize($str, $token_symbols); // 9.75417709351
strtok('', ''); // 9.75421524048
?>
案例 #2 结果:内存仍在使用中
案例 #3 - 再次调用 strtok 并且 unset $str 变量
<?php
$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
?>
案例 #3 结果:内存已释放
所以,更好的 tokenize 函数解决方案
<?php
function tokenize($str, $token_symbols, $token_reset = true) {
$word = strtok($str, $token_symbols);
while (false !== $word) {
// 在这里做一些事情...
$word = strtok($token_symbols);
}
if($token_reset)
strtok('', '');
}
?>
从 URL 中移除 GET 变量
<?php
echo strtok('http://example.com/index.php?foo=1&bar=2', '?');
?>
结果
http://example.com/index.php
对搜索参数进行标记的简单方法,包括双引号或单引号引起来的键。如果只找到一个引号,则字符串的剩余部分将被视为该标记的一部分。
<?php
$token = strtok($keywords,' ');
while ($token) {
// 查找双引号引起来的标记
if ($token{0}=='"') { $token .= ' '.strtok('"').'"'; }
// 查找单引号引起来的标记
if ($token{0}=="'") { $token .= ' '.strtok("'")."'"; }
$tokens[] = $token;
$token = strtok(' ');
}
?>
如果你想要不带引号的输出结果,可以使用 substr(1,strlen($token)) 并且移除添加尾部引号的部分。
可能是在指出显而易见的事情,但如果你更愿意使用 for 循环而不是 while 循环(例如,为了保持标记字符串在同一行以提高可读性),那么是可以实现的。另外的好处是,它也不会在循环本身之外创建 $tok 变量。
然而,缺点是,你无法使用 elarlang 提到的技术手动释放使用的内存。
<?php
for($tok = strtok($str, ' _-.'); $tok!==false; $tok = strtok(' _-.'))
{
echo "$tok </br>";
}
?>
如果你想只用一个字母进行标记,explode() 比 strtok() 快得多。
<?php
$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;
?>
结果是:(PHP 5.3.3 在 CentOS 上)
explode():0.001317024230957 sec.
strtok():0.0058917999267578 sec.
explode() 在短字符串中大约快五倍。
这看起来很简单,但我花了很长时间才弄明白,所以我想我会分享它,以防其他人也想要同样的东西
这应该类似于 substr() 但使用令牌而不是字符串!
<?php
/* subtok(string,chr,pos,len)
*
* chr = 用于分隔令牌的字符
* pos = 起始位置
* len = 长度,如果为负数,则从右边开始计数
*
* 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 将令牌分解成数组,array slice 允许您选择您想要的令牌,然后 implode 将其转换回字符串
虽然它远非克隆,但这受到 mIRC 的 gettok() 函数的启发
请注意,strtok 每次可能接收不同的令牌。因此,例如,如果您希望提取几个词,然后提取句子的其余部分
<?php
$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(""); //注意不同的令牌参数
echo $error_message; //This is a long message explaining the error codes.
?>
从 strtok() 处理空字符串的方式改变开始,它现在对依赖空数据运行的脚本毫无用处。
例如,标准标题。(使用 UNIX 换行符)
http/1.0 200 OK\n
Content-Type: text/html\n
\n
--HTML BODY HERE---
使用 strtok 解析时,人们会等到它找到一个空字符串来指示标题的结束。但是,由于 strtok 现在跳过空段,因此无法知道标题何时结束。
这不能称为“正确”的行为,它当然不是。它使 strtok 无法(正确地)处理一个非常简单的标准。
但是,这种新功能不影响 Windows 风格的标题。您将搜索仅包含“\r”的行
但是,这不能成为更改的理由。
这是一个使用 strtok 函数的类似 Java 的 StringTokenizer 类
<?php
/**
* 字符串令牌化器类允许应用程序将字符串分解为令牌。
*
* @example 以下是令牌化器使用的一个示例。代码:
* <code>
* <?php
* $str = 'this is:@\t\n a test!';
* $delim = ' !@:'\t\n; // 删除这些字符
* $st = new StringTokenizer($str, $delim);
* while ($st->hasMoreTokens()) {
* echo $st->nextToken() . "\n";
* }
* 打印以下输出:
* this
* is
* a
* test
* ?>
* </code>
*/
class StringTokenizer {
/**
* @var string
*/
private $token;
/**
* @var string
*/
private $delim;
/**
* 为指定的字符串构造一个字符串令牌化器
* @param string $str 要令牌化的字符串
* @param string $delim 分隔令牌的定界符集(字符),默认值为 ' '
*/
public function __construct(/*string*/ $str, /*string*/ $delim = ' ') {
$this->token = strtok($str, $delim);
$this->delim = $delim;
}
public function __destruct() {
unset($this);
}
/**
* 测试此令牌化器字符串中是否有更多令牌可用。它
* 不会以任何方式移动内部指针。要将内部指针
* 移动到下一个元素,请调用 nextToken()
* @return boolean - 如果有更多令牌,则为 true,否则为 false
*/
public function hasMoreTokens() {
return ($this->token !== false);
}
/**
* 从此字符串令牌化器返回下一个令牌,并将内部
* 指针向前移动一个位置。
* @return string - 令牌化字符串中的下一个元素
*/
public function nextToken() {
$current = $this->token;
$this->token = strtok($this->delim);
return $current;
}
}
?>
您好,strtok 的葡萄牙语文档是错误的,在示例 (2) 错误的这一部分。
示例 #2 strtok() 的旧行为
<?php
$first_token = strtok('/something', '/');
$second_token = strtok('/');
var_dump ($first_token, $second_token);
?>
上面的示例将产生
string(0) ""
string(9) "something"
(上面的这个示例应该反过来,如下所示:)
正确
string(9) "something"
string(0) ""
(示例 3 是正确的)
示例 #3 strtok() 的新行为
<?php
$first_token = strtok('/something', '/');
$second_token = strtok('/');
var_dump ($first_token, $second_token);
?>
上面的示例将产生
string(9) "something"
bool(false)
请注意,strtok 内存由当前执行的所有 PHP 代码共享,甚至包括包含的文件。如果您不小心,这会以意想不到的方式影响您。
例如
<?php
$path = 'dir/file.ext';
$dir_name = strtok($path, '/');
if ($dir_name !== (new Module)->getAllowedDirName()) {
throw new \Exception('Invalid directory name');
}
$file_name = strtok('');
?>
看起来很简单,但如果您的 Module 类没有加载,这会触发自动加载器。自动加载器 *可能* 在其加载代码中使用 strtok。
或者您的 Module 类 *可能* 在其构造函数中使用 strtok。
这意味着您永远无法正确获取 $file_name。
所以:您应该 *始终* 将 strtok 调用分组,在两次 strtok 调用之间没有任何外部代码。
这将是可以的
<?php
$path = 'dir/file.ext';
$dir_name = strtok($path, '/');
$file_name = strtok('');
if ($dir_name !== (new Module)->getAllowedDirName()) {
throw new \Exception('Invalid directory name');
}
?>
这可能会导致问题
<?php
$path = 'one/two#three';
$a = strtok($path, '/');
$b = strtok(Module::NAME_SEPARATOR);
$c = strtok('');
?>
因为你的自动加载器可能正在使用 strtok。
通过在调用 *之前* 获取 strtok 中使用的所有参数可以避免这种情况
<?php
$path = 'one/two#three';
$separator = Module::NAME_SEPARATOR;
$a = strtok($path, '/');
$b = strtok($separator);
$c = strtok('');
?>
我发现这对于解析用户在文本字段中输入的链接很有用。
例如,这是一个链接 <http://example.com>
function parselink($link) {
$bit1 = trim(strtok($link, '<'));
$bit2 = trim(strtok('>'));
$html = '<a href="'.$bit2.'">'.$bit1.'</a>';
return $html; // <a href="http://example.com">This is a link</a>
}
@maisuma 你颠倒了 explode() 和 strtok() 函数的参数,你的代码没有达到预期效果。
你期望逐个标记读取输入字符串,所以等效于 strtok() 的代码是 arra_filter(explode()),因为 explode() 在读取字符串中有多个连续分隔符时会返回空字符串行,例如两个空格之间的。
实际上,如果读取字符串包含多个连续分隔符,strtok() 比 arra_filter(explode()) 快得多(至少快两倍),
如果读取字符串在标记之间只包含一个分隔符,则速度较慢。
<?php
$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);
//print_r($arr);
$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;
?>
这是一个简单的类,允许你使用 foreach 循环遍历字符串标记。
<?php
/**
* TokenIterator 类允许你使用
* 熟悉的 foreach 控制结构遍历字符串标记。
*
* 例子:
* <code>
* <?php
* $string = 'This is a test.';
* $delimiters = ' ';
* $ti = new TokenIterator($string, $delimiters);
*
* foreach ($ti as $count => $token) {
* echo sprintf("%d, %s\n", $count, $token);
* }
*
* // 打印以下输出:
* // 0. This
* // 1. is
* // 2. a
* // 3. test.
* </code>
*/
class TokenIterator implements Iterator
{
/**
* 要标记的字符串。
* @var string
*/
protected $_string;
/**
* 标记分隔符。
* @var string
*/
protected $_delims;
/**
* 存储当前标记。
* @var mixed
*/
protected $_token;
/**
* 内部标记计数器。
* @var int
*/
protected $_counter = 0;
/**
* 构造函数。
*
* @param string $string 要标记的字符串。
* @param string $delims 标记分隔符。
*/
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;
}
}
?>
从 URL 中移除 GET 变量
<?php
$url = strtok('https://php.net/manual/en/ref.strings.php?foo=1&bar=2', '?');
// $url = 'https://php.net/manual/en/ref.strings.php'
此函数接受一个字符串,并返回一个包含单词(以空格分隔)的数组,同时还考虑引号、双引号、反引号和反斜杠(用于转义内容)。
所以
$string = "cp 'my file' to `Judy's file`";
var_dump(parse_cli($string));
将产生
array(4) {
[0]=>
string(2) "cp"
[1]=>
string(7) "my file"
[2]=>
string(5) "to"
[3]=>
string(11) "Judy's file"
}
它的工作方式是逐个字符地遍历字符串,并根据每个字符及其当前状态 $state 来查找要执行的操作。
操作可以是(一个或多个)将字符/字符串添加到当前单词,将单词添加到输出数组,以及更改或(重新)存储状态。
例如,如果 $state 为 'doublequoted',则空格将成为当前 'word'(或 'token')的一部分,但如果 $state 为 'unquoted',则空格将开始一个新的 token。
后来我被告知这是一个“使用有限状态自动机的词法分析器”。谁知道呢 :-)
<?php
#_____________________
# parse_cli($string) /
function parse_cli($string) {
$state = 'space';
$previous = ''; // 存储遇到反斜杠时的当前状态(它将 $state 更改为 'escaped',但随后必须回退到上一个 $state)
$out = array(); // 返回值
$word = '';
$type = ''; // 字符类型
// 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') {
// 一次性获取所有紧随当前字符的也是 'other' 的字符
preg_match("/[ \'\"\`\\\]/", $string, $matches, PREG_OFFSET_CAPTURE, $i);
if ($matches) {
$matches = $matches[0];
$char = substr($string, $i, $matches[1]-$i); // 是的,$char 长度可以大于 1
$i = $matches[1] - 1;
}else{
// 在特殊字符上不再匹配,这意味着这必须是最后一个单词!
// 以下的 .= 是因为我们可能处于一个刚刚包含特殊字符的单词的中间位置
$word .= substr($string, $i);
break; // 跳出 for() 循环
}
}
$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;
}
?>
这个例子希望能帮助你理解这个函数是如何工作的
<?php
$selector = 'div.class#id';
$tagname = strtok($selector,'.#');
echo $tagname.'<br/>';
while($tok = strtok('.#'))
{
echo $tok.'<br/>';
}
?>
输出
div
class
id
以下是我写的一个小函数,因为我需要从字符串中提取一些命名的 token(类似于 Google)。例如,我需要将像 "extension:gif size:64M animated:true author:'John Bash'" 这样的字符串格式化为
array(
'extension' => 'gif',
'size' => '64M',
'animated' => true,
'author' => 'John Bash'
)
所以,这是代码
<?php
header('Content-type: text/plain; charset=utf-8');
/**
* 注意:使用 mbstring.func_overload 对该函数的 多字节支持
*
* @param string $string 要标记化的字符串
* @param int $offset 起始偏移量
* @param string $defaultTokenName 如果没有指定,则为默认标记名称
* @param string $groupDelimiters 标记组的定界符
* @param string $groupNameDelimiter 标记组名称的定界符
* @return array
*/
function getTokens(
$string,
$offset = 0,
$defaultTokenName = null,
$groupDelimiters = '\'"',
$groupNameDelimiter = ':')
{
if ($offset >= strlen($string)) {
//echo "offset out of range";
return false;
}
$spaces = " \t\n\r"; // 空格字符
// 将组定界符添加到空格中...
$groupSpaces = $spaces . $groupNameDelimiter;
$delimiters = $groupSpaces . $groupDelimiters;
//var_dump($groupSpaces);
$string = ltrim(substr($string, $offset), $groupSpaces);
$token_strings = array();
//echo "String is : " . $string . "\n";
// 1. 拆分所有标记...
while ($offset < strlen($string)) {
$lastOffset = $offset;
$escaped = false;
if (false !== strpos($groupDelimiters, $char = $string[$offset])) {
$groupChar = $char;
} else {
$groupChar = null;
}
if (null !== $groupChar) {
while (($offset < strlen($string)) && (($groupChar !== ($char = $string[++$offset])) || $escaped)) {
//$offset++;
$escaped = ('\\' === $char);
}
$offset++;
//echo "*** Grouped : " . substr($string, $lastOffset, $offset - $lastOffset) . "\n";
} else {
while (($offset < strlen($string)) && ((false === strpos($delimiters, $char = $string[$offset])) || $escaped)) {
$offset++;
$escaped = ('\\' === $char);
}
//echo "*** Non-group : " . substr($string, $lastOffset, $offset - $lastOffset) . "\n";
}
//跳过空格...
while (($offset < strlen($string)) && ((false !== strpos($groupSpaces, $char = $string[$offset])) || $escaped)) {
$offset++;
$escaped = ('\\' === $char);
}
$token_strings[] = substr($string, $lastOffset, $offset - $lastOffset);
//echo "Next token = '" . end($token_strings) . "'\n";
}
$tokens = array();
$tokenName = null;
foreach ($token_strings as $token_str) {
// 清理 $token_str
$token_str = trim(stripslashes($token_str), $spaces);
$str_value = trim($token_str, $delimiters);
switch (strtolower($str_value)) {
case 'true': $str_value = true; break;
case 'false': $str_value = false; break;
default: break;
}
// 它是一个标记名称吗?
if (':' === substr($token_str, -1, 1)) {
if (!empty($tokenName)) {
$tokens[$tokenName] = '';
}
$tokenName = trim($token_str, $delimiters);
} else {
if (!empty($tokenName)) {
if (isset($tokens[$tokenName])) {
$tokens[$tokenName] = array(
$tokens[$tokenName],
$str_value
);
} else {
$tokens[$tokenName] = $str_value;
}
$tokenName = null;
} elseif (empty($defaultTokenName)) {
$tokens[] = trim($token_str, $delimiters);;
} else {
if (isset($tokens[$defaultTokenName])) {
$tokens[$defaultTokenName] = array(
$tokens[$defaultTokenName],
$str_value
);
} else {
$tokens[$defaultTokenName] = $str_value;
}
}
}
}
if (!empty($tokenName)) {
$tokens[$tokenName] = '';
}
return $tokens;
}
$str = "check1: test "
. "check2:'hello world' "
. 'check3: "foo" '
. "check4: \\\"try this\\\""
. '"buz" '
. 'check1:true';
?>