1

How do you turn this text:

NEW LOW FOR US-PAKISTAN RELATIONS

into this text:

New Low For US-Pakistan Relations

PHP's strtolower(ucwords($string)) would turn "US-PAKISTAN" into "Us-pakistan". However, I'd require the acronym "US" and the "P" from Pakistan to stay uppercase. How can I best achieve that?

Tomi Seus
  • 1,131
  • 2
  • 13
  • 28
  • This question needs more context than just one sample string to offer definitive advice. Even with a lookup array / dictionary, php will not reliably cover all possible cases. This question seems to be a rabbit hole. Because we don't know of more exceptions than just `US`, this question is Unclear. Furthermore, the hyphen may be an irrelevant indicator. If the input string has `us` as a stand alone word, it could be correctly handled as `us` and `US` but php will never know. Same with `can` ... is that the Olympic abbreviation for Canada? or just the verb `can`? I think I'll vote Too Broad. – mickmackusa Dec 03 '18 at 05:21
  • Relevant: https://stackoverflow.com/a/17817754/2943403 – mickmackusa Aug 13 '21 at 09:27

3 Answers3

3

Check the comments in PHP's documentation for ucwords(). They cover these issues of hyphens and exceptions, as well as offer solutions.

Ayman Safadi
  • 11,502
  • 1
  • 27
  • 41
2

As for US: You’d need a database storing the words that shall be uppercase. PHP itself is stupid, it does not know if you mean United States or us (accusative of we). Thus, the interpreter cannot decide if US in US-Pakistan is meant to be the abbreviation or the pronoun.

With such a database, you would call your upper function normally. Afterwards you would have to check if the entry is within your database and replace the occurrence in the text with the one from the database.

$string = strtolower(ucwords($string));
$words = preg_split('/\s+/', $string);
foreach ($words as $word) {
    // search case-independantly
    if (null !== ($correctForm = searchDatabase($word))) {
        str_replace($word, $correctFrom, $string);
    }
}

This is probably not optimal, but I hope it is visible what’s the way to go if PHP cannot know if a word is an abbreviation or not.

In the database you might have such entries:

us-pakistan US-Pakistan
us-politician US-politician

Or if you wanna implement it somewhat advanced even:

us-* US-*

In such a case you might also just implement it with a lot of preg_replaces(), but don’t ask me about time consumption. I guess both of these ideas are pretty slow.

As for Pakistan: Keeping letters after dashes capital is easier. You could replace - with - surrounded by spaces ([space]-[space]) before calling the function, then PHP would think that both of them are single words. Afterwards you could replace the [space]-[space] construction with a simple dash again.

str_replace(' - ', '-', strtolower(ucwords(str_replace('-', ' - ', $string))));

Check out the PHP-comments Ayman Safadi has posted, I guess they have much better solutions for this problem (mine was just: “What’s the first maximum-short solution coming to my mind?”).

aufziehvogel
  • 7,167
  • 5
  • 34
  • 56
  • thanks for your input. do you know any downloadable DBs for acronyms and abbreviations? I saw that [wikipedia had a great list of acronyms](http://en.wikipedia.org/wiki/List_of_acronyms_and_initialisms), but I still haven't figured out how to download it. any ideas? – Tomi Seus Jan 01 '12 at 12:46
  • No, I don’t know. Can just google for it too, and I only found [one](http://www.textfiles.com/humor/acronyms.txt), but I guess it only includes some. – aufziehvogel Jan 01 '12 at 14:16
0

You can try the following code to achieve the desired results.In this code we first have converted whole string into lower case then used ucwords() function to get the whole string in title case then we hence used str_replace to achieve the specific output.

Code:

<?php
$a="NEW LOW FOR US-PAKISTAN RELATIONS";
$b=ucwords(strtolower($a));
$c=str_replace("Us-pakistan","US-Pakistan","$b");
echo $c;
?>

Output:

New Low For US-Pakistan Relations
atif
  • 87
  • 1
  • 3