ucwords function with exceptions
Asked Answered
N

6

3

I need some help i have this code that Uppercase the first character of each word in a string with exceptions i need the function to ignore the exception if it's at the beginning of the string:

function ucwordss($str, $exceptions) {
$out = "";
foreach (explode(" ", $str) as $word) {
$out .= (!in_array($word, $exceptions)) ? strtoupper($word{0}) . substr($word, 1) . " " : $word . " ";
}
return rtrim($out);
}

$string = "my cat is going to the vet";
$ignore = array("is", "to", "the");
echo ucwordss($string, $ignore);
// Prints: My Cat is Going to the Vet

this is what im doing:

$string = "my cat is going to the vet";
$ignore = array("my", "is", "to", "the");
echo ucwordss($string, $ignore);
// Prints: my Cat is Going to the Vet
// NEED TO PRINT: My Cat is Going to the Vet
Nitpicking answered 16/8, 2012 at 22:39 Comment(1)
btw, you may use ucfirst instead of strtoupper($word{0}) . substr($word, 1)Horatio
P
4
- return rtrim($out);
+ return ucfirst(rtrim($out));
Publicize answered 16/8, 2012 at 22:46 Comment(0)
H
3

Something like this:

function ucwordss($str, $exceptions) {
    $out = "";
    foreach (explode(" ", $str) as $key => $word) {
        $out .= (!in_array($word, $exceptions) || $key == 0) ? strtoupper($word{0}) . substr($word, 1) . " " : $word . " ";
    }
    return rtrim($out);
}

Or even easier, before return in your function make strtoupper first letter

Horatio answered 16/8, 2012 at 22:43 Comment(0)
C
1

Do this really cheaply by just always uppercasing your first word:

function ucword($word){
    return strtoupper($word{0}) . substr($word, 1) . " ";
}

function ucwordss($str, $exceptions) {
    $out = "";
    $words = explode(" ", $str);
    $words[0] = ucword($words[0]);
    foreach ($words as $word) {
        $out .= (!in_array($word, $exceptions)) ? ucword($word)  : $word . " ";
    }
    return rtrim($out);
}
Crosswise answered 16/8, 2012 at 22:44 Comment(0)
A
0

what about you make the first letter in the string upper case so no matter your mix you will still come through

$string = "my cat is going to the vet";
$string = ucfirst($string);
$ignore = array("is", "to", "the");
echo ucwordss($string, $ignore);

this way you first letter of the string will always be upper case

Ascogonium answered 16/8, 2012 at 22:56 Comment(0)
C
0

preg_replace_callback() will allow you to express your conditional replacement logic in a loopless and dynamic fashion. Consider this approach that will suitably modify your sample data:

Code: (PHP Demo) (Pattern Demo)

$string = "my cat is going to the vet";
$ignore = array("my", "is", "to", "the");
$pattern = "~^[a-z]+|\b(?|" . implode("|", $ignore) . ")\b(*SKIP)(*FAIL)|[a-z]+~";
echo "$pattern\n---\n";
echo preg_replace_callback($pattern, function($m) {return ucfirst($m[0]);}, $string);

Output:

~^[a-z]+|\b(?|my|is|to|the)\b(*SKIP)(*FAIL)|[a-z]+~
---
My Cat is Going to the Vet

You see, the three piped portions of the pattern (in order) make these demands:

  1. If the start of the string is a word, capitalize the first letter.
  2. If a "whole word" (leveraging the \b word boundary metacharacter) is found in the "blacklist", disqualify the match and keep traversing the input string.
  3. Else capitalize the first letter of every word.

Now, if you want to get particular about contractions and hyphenated words, then you only need to add ' and - to the [a-z] character classes like this: [a-z'-] (Pattern Demo)

If anyone has a fringe cases that will break my snippet (like "words" with special characters that need to be escaped by preg_quote()), you can offer them and I can offer a patch, but my original solution will adequately serve the posted question.

Coordination answered 3/12, 2018 at 4:7 Comment(0)
M
0

This function should do the same thing, but with custom delimitators like in the original function.

function ucwordsexcept($str, $exceptions, $delims=' ',) {
    $out = array($str);
    foreach (str_split($delims) as $key => $delim) {
        $out[$key+1] = '';
        foreach (explode($delim, $out[$key]) as $word) {
            $out[$key+1] .= !in_array($word, $exceptions) ? strtoupper($word[0]).substr($word, 1).$delim:$word.$delim;
        }
        $out[$key+1] = rtrim($out[$key+1], $delim);
    }
    return ucfirst(end($out));
}
Mclyman answered 28/10 at 5:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.