27

Is there any difference between the ToUpper and the ToTitle function?

Rene Knop
  • 1,788
  • 3
  • 15
  • 27
jasonz
  • 1,315
  • 1
  • 17
  • 31
  • 1
    Have you tried them? Did you notice a difference? – JJJ Sep 01 '13 at 14:57
  • I don't find out. The source codes are the same. – jasonz Sep 01 '13 at 15:05
  • In theory the conversion to tittle and to uppercase aren't the same. But I don't have any example of difference. This is more related to Unicode than to Go, I think. – Denys Séguret Sep 01 '13 at 15:11
  • 2
    @dystroy There are a few cases. U+01F3 LATIN SMALL LETTER DZ for example. Upper case is U+01F1, title case is U+01F2. http://www.fileformat.info/info/unicode/char/01f3/index.htm – topskip Sep 01 '13 at 18:00
  • [Difference between uppercase and titlecase](https://stackoverflow.com/q/31770995/995714) – phuclv Aug 29 '18 at 17:19

6 Answers6

14

See this example on the difference of titlecase/uppercase:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "dz"
    fmt.Println(strings.ToTitle(str))
    fmt.Println(strings.ToUpper(str))
}

(Note "dz" here is a single character, not a "d" followed by a "z": dz vs dz)

http://play.golang.org/p/xpDPLqKM9C

River
  • 8,585
  • 14
  • 54
  • 67
topskip
  • 16,207
  • 15
  • 67
  • 99
  • Really thanks. But it doesn't work in my laptop ``go 1.1.2 3.10.9 x86_64 GNU/Linux en_US.UTF-8``. – jasonz Sep 02 '13 at 03:43
  • @JasonZhang doesn't work means what? Can't see the difference? Compile error? – topskip Sep 02 '13 at 05:50
  • It still prints out ``DZ``. – jasonz Sep 02 '13 at 06:13
  • Screenshot [here](https://www.dropbox.com/s/kcy0rgmcyv5bemt/2013-09-02-140823_1366x768_scrot.png) – jasonz Sep 02 '13 at 06:23
  • @JasonZhang perhaps a font problem? You can try this: http://play.golang.org/p/oSQmAwKSGj and see what bytes are created – topskip Sep 02 '13 at 07:43
  • Ahh, [dz](http://www.fileformat.info/info/unicode/char/01f3/index.htm) is not ``dz``(I've never seen it before)... But how can I print out it? Both of my ``$LC_CTYPE`` and ``$LANG`` are ``en_US.UTF-8``. Maybe not ``en_US``? ``Latin``? – jasonz Sep 02 '13 at 09:40
  • 1
    In this specific case (and probably other similar ones) this example explains it well. Kudos! – Gaurav Ojha Dec 12 '16 at 12:09
  • I hope you live in a world, where Copy&Paste was already invented. – metalim Oct 10 '18 at 05:20
13

I had the same problem. You want to use the strings.Title() method not the strings.ToTitle() method.

http://golang.org/pkg/strings/#Title

Brenden
  • 7,708
  • 11
  • 61
  • 75
7

For a truly title case converting function, you must use -

strings.Title(strings.ToLower(str))

I tried the answers for converting a string to title case and none of the following works in case of a word which already has all uppercase characters or text that has few letters in uppercase and few in lowercase.

Here's a comprehensive check on what does what - http://ideone.com/r7nVbZ

I'm pasting the results here -

Given Text:  title case
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  Title Case
ToLower then Title:  Title Case
-------------------------------

Given Text:  Title Case
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  Title Case
ToLower then Title:  Title Case
-------------------------------

Given Text:  TITLE CASE
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  TITLE CASE
ToLower then Title:  Title Case
-------------------------------

Given Text:  TiTlE CasE
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  TiTlE CasE
ToLower then Title:  Title Case
-------------------------------

Given Text:  Title case
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  Title Case
ToLower then Title:  Title Case
-------------------------------

Given Text:  title CASE
ToTitle:  TITLE CASE
ToUpper:  TITLE CASE
Title:  Title CASE
ToLower then Title:  Title Case
Gaurav Ojha
  • 1,147
  • 1
  • 15
  • 37
  • Wow. That is infuriating, at least for English. Thanks for pointing this out. I had tried other solutions and had the same problem with already uppercase text. – Chris Redford Oct 23 '20 at 13:13
5

The strings.Title function is deprecated. The following is now the correct way to do this:

package main

import (
    "fmt"

    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func main() {
    caser := cases.Title(language.English)
    fmt.Println(caser.String("the quick brown fox jumps over the lazy dog"))
}

Result:

The Quick Brown Fox Jumps Over The Lazy Dog

Program exited.

https://go.dev/play/p/l1uCxNEiTPT

Matthew Ratzloff
  • 4,518
  • 1
  • 31
  • 35
3

According to unicode.org

"Because of the inclusion of certain composite characters for compatibility, such as U+01F1 latin capital letter dz, a third case, called titlecase, is used where the first character of a word must be capitalized. An example of such a character is U+01F2 latin capital letter d with small letter z. The three case forms are UPPERCASE, Titlecase, and lowercase."

This means that when you use ToTitle or ToUpper for characters like dz, you'll probably not be able to visually distinguish the result, but the two methods will return different unicode code points.

dz           = "\u01f3"
ToUpper(dz)  = "\u01f1"
ToTittle(dz) = "\u01f2"

https://play.golang.org/p/OAjONd87y2

jff
  • 476
  • 5
  • 10
2

Even though you're saying in your comment that "The source codes are the same." it's actually not the case (see L255 vs L277). Therefore those two function perform different tasks, exactly as documented. For the definition of "upper case" and "title case" please see the documentation at unicode.org.

zzzz
  • 87,403
  • 16
  • 175
  • 139
  • 1
    I don't really understand [to](http://golang.org/src/pkg/unicode/letter.go#L206). But when I try ``fmt.Println(strings.ToTitle("Go titlE"))``, it prints out ``GO TITLE`` just like ``strings.ToUpper("go title")`` does. Maybe it is [All-uppercase letters](http://en.wikipedia.org/wiki/Title_case#Headings_and_publication_titles). – jasonz Sep 01 '13 at 16:27
  • 1
    The results are *correct* and it is working as *documented*, but that in no way means the two function do the same thing in the general case. See also [this line](http://golang.org/src/pkg/unicode/letter.go#L272). – zzzz Sep 01 '13 at 16:53