格式化PHP中的项目列表

通常编写项目列表以逗号分隔每个项目,最后两个项目除外,后两个项目用单词“和”分隔。我最近需要实现一个函数,该函数接受一个字符串并将其转换为这种类型的列表,因此我想我将对其进行扩展并将其发布在此处。

该函数采用单个参数,该参数可以是数组或逗号分隔的字符串。如果将数组传递给函数,则将其转换为逗号分隔的字符串,然后传递给函数的下一部分。然后,该函数将删除所有结尾的逗号,之间没有任何逗号的逗号,然后确保每个逗号后都有一个空格。最后一步是用单词“和”替换最后一个逗号。操作完成后,将返回结果字符串。如果字符串(除去任何结尾的逗号后)不包含任何逗号,则仅返回该字符串。

这是完整的功能,将对每个步骤进行注释。

/**
 * This function will take a string in the format of a single item or
 * multiple items in the format 1,2,3,4,5 or an array of items.
 * The output will be a readable set of items with the last two items 
 * separated by " and ".
 *
 * @param  string|array $numbers The list of items as a string or array.
 * @return string                The formatted items.
 */
function formatItems($numbers)
{
    if (is_array($numbers)) {
        // 如果数字是一个数组,则将其内推成逗号分隔的字符串。
        $numbers = implode(',', $numbers);
    }
 
    if (is_string($numbers)) {
        // 确保所有逗号后都有一个空格字符。
        $numbers = preg_replace("/(\s*?,\s*)/", ", ", $numbers);
        // 删除所有多余的逗号
        $numbers = preg_replace("/(,\s)+/", ", ", $numbers);        
        // 该字符串包含逗号,请找到字符串中的最后一个逗号。
        $lastCommaPos = strrpos($numbers, ',') - strlen($numbers);
        // 将逗号的最后一次出现替换为“和”" and "
        $numbers = substr($numbers, 0, $lastCommaPos) . str_replace(',', ' and', substr($numbers, $lastCommaPos));
    }
    return $numbers;
}

以下是此功能的一些使用实例。

echo formatItems('1');
echo formatItems('1,2');
echo formatItems('1,2,3,4,5,6,7');
echo formatItems(range(1,6));
echo formatItems(range('a','g'));
echo formatItems('sdfgdf g,sdf, g,dfg,df,g ,df g,df,g ,d fg');
echo formatItems('1.45/76,5/,85/6.,45./6,456');
echo formatItems('sdfah,      ,,, ,, ,,,, ,  ,  ,  [email protected])_}_:{>9l,65653224,253,4,236,56,98./,978/59');
echo formatItems('4575,8 56,456,36,45656      ,,    , 4, 56, 546, 546, , 6, 456, , ');

此代码产生以下输出。

1
1 and 2
1, 2, 3, 4, 5, 6 and 7
1, 2, 3, 4, 5 and 6
a, b, c, d, e, f and g
sdfgdf g, sdf, g, dfg, df, g, df g, df, g and d fg
1.45/76, 5/, 85/6., 45./6 and 456
sdfah, [email protected])_}_:{>9l, 65653224, 253, 4, 236, 56, 98./ and 978/59
4575, 8 56, 456, 36, 45656, 4, 56, 546, 546, 6 and 456

更新:2010年8月5日

感谢Carl找到了一个关于在函数中如何看待凌乱的字符串中的逗号的小错误。我快速浏览了为清除用户输入的项目列表而编写的代码,并将其包含在此代码中。这是该功能的新版本。

/**
 * This function will take a string in the format of a single item or
 * multiple items in the format 1,2,3,4,5 or an array of items.
 * The output will be a readable set of items with the last two items 
 * separated by " and ".
 *
 * @param  string|array $numbers The list of items as a string or array.
 * @return string                The formatted items.
 */
function formatItems($numbers)
{
    if (is_array($numbers)) {
        // 如果数字是一个数组,则将其内推成逗号分隔的字符串。
        $numbers = implode(',', $numbers);
    }
 
    if (is_string($numbers)) {
        /* 
	    Make sure all commas have a single space character after them and that	
	    there are no double commas in the string.
	    */	
	    $numbers = trim($numbers);
	    $patterns[0] = '/\s*,\s*/';
	    $patterns[1] = '/,{2,}/';
	    $patterns[2] = '/,+$/';
	    $patterns[3] = '/^,+/';
	    $patterns[4] = '/,/';
	    $replacements[0] = ',';
	    $replacements[1] = ',';
	    $replacements[2] = '';
	    $replacements[3] = '';
	    $replacements[4] = ', ';
	    $numbers= preg_replace($patterns, $replacements, $numbers);
 
        // 该字符串包含逗号,请找到字符串中的最后一个逗号。
        $lastCommaPos = strrpos($numbers, ',') - strlen($numbers);
 
        // 将逗号的最后一次出现替换为“和”" and "
        $numbers = substr($numbers, 0, $lastCommaPos) . str_replace(',', ' and ', substr($numbers, $lastCommaPos));
    }
    return $numbers;
}