public static function ucwords($str, $encoding = null)
    {
        $encoding = $encoding === null ? mb_internal_encoding() : $encoding;

        // Note: [\x0c\x09\x0b\x0a\x0d\x20] matches;
        // form feeds, horizontal tabs, vertical tabs, linefeeds and carriage returns
        // This corresponds to the definition of a "word" defined at http://www.php.net/ucwords
        $pattern = '/(^|([\x0c\x09\x0b\x0a\x0d\x20]+))([^\x0c\x09\x0b\x0a\x0d\x20]{1})[^\x0c\x09\x0b\x0a\x0d\x20]*/u';

        return preg_replace_callback(
            $pattern,
            function ($matches) use ($encoding) {
                $leadingws = $matches[2];
                $ucfirst = static::strtoupper($matches[3], $encoding);
                $ucword = static::substrReplace(ltrim($matches[0]), $ucfirst, 0, 1);

                return $leadingws . $ucword;
            },
            $str
        );
    }