除了文章,连词和介词之外,每个单词的首字母大写

时间:2012-08-08 18:40:17

标签: php codeigniter tags

我正在为使用Codeigniter构建的自定义CMS编写标签系统,我正在尝试强制执行特定格式。

基本上,我需要将每个单词的第一个字母大写,但以下情况除外,它应该是小写的:

  • 文章:a,an,
  • 协调连词:and,but,or,for,nor,etc。
  • 介词(少于五个字母):with,on,at,to,from,by等。

此外,如果标签以上述之一开头,则应将其大写。

格式正确的标签的一些示例:

  • 权力的游戏
  • 我和男人
  • 从头到尾
  • 指环王
  • 极品飞车

到目前为止我只有:

$tag = 'Lord of the Rings';
$tag = ucwords($tag); 

$patterns = array('/A/', '/An/', '/The/', '/And/', '/Of/', '/But/', '/Or/', '/For/', '/Nor/', '/With/', '/On/', '/At/', '/To/', '/From/', '/By/' );
$lowercase = array('a', 'an', 'the', 'and', 'of', 'but', 'or', 'for', 'nor', 'with', 'on', 'at', 'to', 'from', 'by' );

$formatted_tag = preg_replace($patterns, $lowercase, $tag);

// capitalize first letter of string
$formatted_tag = ucfirst($formatted_tag);

echo $formatted_tag;

这会产生指环王的正确结果,但是如何避免重复数组呢?当我添加新单词时,将它们匹配起来很乏味。

我确信有一些词我应该被包含在内,是否有我可以使用的现有功能或类?

1 个答案:

答案 0 :(得分:6)

如果您使用preg_replace_callback()的自定义回调,则不需要$lowercase数组。此外,您当前的方法需要字边界,否则它会将Android替换为androidbAnd替换为band。最后,为N个单词创建N个正则数是低效的,没有必要,因为这可以用一个正则表达式完成。

我会保留一个单词数组:

$words = array('A', 'An', 'The', 'And', 'Of', 'But', 'Or', 'For', 'Nor', 'With', 'On', 'At', 'To', 'From', 'By' );

创建一个动态正则表达式,完成字边界,如下所示:

$regex = '/\b(' . implode( '|', $words) . ')\b/i';

现在用小写字母替换所有匹配项:

$formatted_tag = preg_replace_callback( $regex, function( $matches) {
    return strtolower( $matches[1]);
}, $tag);