我正在为使用Codeigniter构建的自定义CMS编写标签系统,并且正在尝试强制执行特定格式。
基本上,我需要将每个单词的第一个字母大写,但以下内容除外,它们应该是小写的:
- 文章: a, an,
- 协调连词:和,但是,或,为,或等。
- 介词(少于五个字母):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;
这会产生指环王的正确结果,但我如何避免重复数组?当我添加新单词时,将它们匹配起来很乏味。
我确定应该包含一些我缺少的单词,是否有任何现有的函数或类可供我使用?
如果您将自定义回调与 preg_replace_callback()
一起使用,则不需要 $lowercase
数组。此外,您当前的方法需要单词边界,否则它将用android
替换Android
或用band
替换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);