来自字符串的PHP标记

时间:2010-11-15 19:01:03

标签: php tokenize

假设您有一个如下所示的字符串: token1 token2 tok3

你想获得所有的标记(特别是空格之间的字符串),还有它们的位置(偏移量)和长度。

所以我想要一个看起来像这样的结果:

array(
    array(
        'value'=>'token1'
        'offset'=>0
        'length'=>6
    ),
    array(
        'value'=>'token2'
        'offset'=>7
        'length'=>6
    ),
    array(
        'value'=>'tok3'
        'offset'=>14
        'length'=>4
    ),
)

我知道这可以通过简单地遍历字符串的字符来完成,我可以简单地编写一个函数来执行此操作。

我想知道,PHP是否有内置功能可以高效地执行此操作,或者至少可以帮助解决部分问题?

我正在寻找建议并感谢任何帮助。感谢

4 个答案:

答案 0 :(得分:4)

您可以将preg_match_all PREG_OFFSET_CAPTURE 标志一起使用:

$str = 'token1 token2 tok3';
preg_match_all('/\S+/', $str, $matches, PREG_OFFSET_CAPTURE);
var_dump($matches);

然后你只需要替换$matches[0]中的项目,如下所示:

function update($match) {
    return array( 'value' => $value[0], 'offset' => $value[1], 'length' => strlen($value[0]));
}   
array_map('update', $matches[0]);
var_dump($matches[0]);

答案 1 :(得分:4)

在大多数方面,有一种更简单的方法。你会得到一个更基本的结果,但是投入的工作要少得多。

假设您已将tokena tokenb tokenc存储在$ data

$tokens = explode(' ', $data);

现在你有一个由空格分隔的标记数组。它们将是有序的,所以$ tokens [0] = tokena,$ tokens [1] = tokenb等。你可以通过strlen($tokens[$index]);非常容易地得到任何给定项目的长度如果你需要知道多少您通过的令牌,使用$token_count = count($tokens);

不那么复杂,但接下来没有工作要做到。

答案 2 :(得分:1)

您可以使用explode(),它将为您提供字符串中的标记数组,以及strlen()来计算字符串中的字符数。据我所知,我不认为有一个PHP函数可以告诉你元素在数组中的位置。

要解决最后一个问题,您可以使用循环遍历explod() ed数组的计数器变量(foreach()for())并在新数据中提供每个子数组它的位置。

如果我错了,请纠正我。

詹姆斯

答案 3 :(得分:0)

我最喜欢第一个答案 - 使用PREG_OFFSET_CAPTURE。如果其他人感兴趣的话,我最后也写了一些这样做的东西,虽然我会接受第一个答案。

谢谢大家的帮助!

function get_words($string) {
    $string_chars = str_split($string);

    $words = array();
    $curr_offset = 0;

    foreach($reduced_string_chars as $offset=>$char) {
        if ($char == ' ') {
            if ($length) $words[] = array('offset'=>$curr_offset,'length'=>$length,'value'=>implode($value_array));

            $curr_offset = $offset;
            $length = 0;
            $value_array = array();
        }
        else {
            $length++;
            $value_array[] = $char;
        }

    }

    return $words;
}