我想使用分词器函数来计算源代码行数,包括注释计数。尝试使用正则表达式来执行此操作效果不佳,因为存在/*出现在字符串中或其他情况。token_get_all()函数通过正确检测所有注释使此任务变得容易。但是,它不会对换行符进行分词。我编写了以下函数集来将换行符也作为T_NEW_LINE进行分词。
<?php
define('T_NEW_LINE', -1);
function token_get_all_nl($source)
{
$new_tokens = array();
// 获取所有token
$tokens = token_get_all($source);
// 将换行符拆分成独立的token
foreach ($tokens as $token)
{
$token_name = is_array($token) ? $token[0] : null;
$token_data = is_array($token) ? $token[1] : $token;
// 不要拆分封装字符串或多行注释
if ($token_name == T_CONSTANT_ENCAPSED_STRING || substr($token_data, 0, 2) == '/*')
{
$new_tokens[] = array($token_name, $token_data);
continue;
}
// 按换行符拆分数据
$split_data = preg_split('#(\r\n|\n)#', $token_data, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
foreach ($split_data as $data)
{
if ($data == "\r\n" || $data == "\n")
{
// 这是一个换行符token
$new_tokens[] = array(T_NEW_LINE, $data);
}
else
{
// 使用原始token名称添加token
$new_tokens[] = is_array($token) ? array($token_name, $data) : $data;
}
}
}
return $new_tokens;
}
function token_name_nl($token)
{
if ($token === T_NEW_LINE)
{
return 'T_NEW_LINE';
}
return token_name($token);
}
?>
示例用法
<?php
$tokens = token_get_all_nl(file_get_contents('somecode.php'));
foreach ($tokens as $token)
{
if (is_array($token))
{
echo (token_name_nl($token[0]) . ': "' . $token[1] . '"<br />');
}
else
{
echo ('"' . $token . '"<br />');
}
}
?>
我相信你可以用这些函数计算代码行数和注释行数。这比我之前用正则表达式计算代码行数的尝试有了巨大的改进。我希望这对其他人有所帮助,就像过去这个网站上许多用户贡献的示例帮助过我一样。