Php 当字母位于括号内时,自定义UCWord失败

Php 当字母位于括号内时,自定义UCWord失败,php,Php,我有一个美化的ucwords函数,它允许我的系统有选择地允许/禁止字符串中的单词为所有大写字母: function NormalizeWords($str, $disallowAllUppercase = false){ $parts = explode(' ', $str); if($disallowAllUppercase){ $result = array_map(function($x){ return ucwords(strto

我有一个美化的
ucwords
函数,它允许我的系统有选择地允许/禁止字符串中的单词为所有大写字母

function NormalizeWords($str, $disallowAllUppercase = false){
    $parts = explode(' ', $str);

    if($disallowAllUppercase){
        $result = array_map(function($x){
            return ucwords(strtolower($x));
        }, $parts);
    }else{
        $result = array_map(function($x){
            if (!(strtoupper($x) == $x)) {
                return ucwords(strtolower($x));
            }
            return $x;
        }, $parts);
    }

    return implode(' ', $result);
}
此功能几乎在所有情况下都有效。当一个单词在括号内(或者我假设的任何非字母数字字符)时,它就失败了

以下是一些例子:

writeme(NormalizeWords("Make An Omelette (template)", true));
writeme(NormalizeWords("make an omelette (template)", true));
writeme(NormalizeWords("Make An Omelette - template", true));
结果:

Make An Omelette (template) - wrong
Make An Omelette (template) - wrong
Make An Omelette - Template - right
预期成果:

Make An Omelette (Template)
Make An Omelette (Template)
Make An Omelette - Template
您可以看到,当一个单词或多个单词碰到括号或其他字符时,第一个字母不会被强制使用。如何修复函数以执行此操作


提前感谢。

通过将函数更改为使用
preg\u split
来拆分任何非字母字符上的字符串,您只能提取用于大写的单词。通过使用
PREG\u SPLIT\u DELIM\u CAPTURE
标志,我们保留了所有非字母字符,然后我们可以使用
内爆
将字符串重新组合在一起,不使用胶水:

function NormalizeWords($str, $disallowAllUppercase = false){
    $parts = preg_split('/([^A-Za-z]+)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    if($disallowAllUppercase){
        $result = array_map(function($x){
            return ucwords(strtolower($x));
        }, $parts);
    }else{
        $result = array_map(function($x){
            if (!(strtoupper($x) == $x)) {
                return ucwords(strtolower($x));
            }
            return $x;
        }, $parts);
    }
    return implode('', $result);
}

echo(NormalizeWords("Make AN Omelette (template)", false)) . PHP_EOL;
echo(NormalizeWords("make AN omelette (template)", true)) . PHP_EOL;
echo(NormalizeWords("Make An Omelette - template", true)) . PHP_EOL;
输出:

Make AN Omelette (Template)
Make An Omelette (Template)
Make An Omelette - Template

注意:通过将
$disallowAllUppercase
传递到
数组映射
函数,可以简化函数:

function NormalizeWords($str, $disallowAllUppercase = false){
    $parts = preg_split('/([^A-Za-z]+)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    $result = array_map(function ($x) use ($disallowAllUppercase) {
        if ($disallowAllUppercase || strtoupper($x) != $x) {
            return ucwords(strtolower($x));
        }
        return $x;
    }, $parts);
    return implode('', $result);
}

一种解决方法是使用简单的一行程序
mb\u convert\u case()
函数,顺便说一句,您可以将它包装到NormalizeWords函数中

<?php
$text= "Make (an) omelette (template)";
echo mb_convert_case($text, MB_CASE_TITLE, "UTF-8");
?>


工作演示

或者,您可以临时将paren替换为无法识别的单词,然后将其放回
规范化单词之后

$str = 'make an omelette (template)';
$str = str_ireplace('(','unrgcswzbl ',$str); 
$str = str_ireplace(')','unrgcswzbl2 ',$str);
$str = NormalizeWords( $str,true);
$str = str_ireplace('unrgcswzbl ','',$str);
$str = str_ireplace('unrgcswzbl2 ','',$str);
echo $str;

@别担心。我很高兴能帮上忙。但是请看我的编辑,我已经简化了函数中的代码。您是否尝试使用
mb\u convert\u case()