Conor
Conor

Reputation: 791

Make first letter of words uppercase in a string

I have a large array of strings such as this one:

"INTEGRATED ENGINEERING 5 Year (BSC with a Year in Industry)"

I want to capitalise the first letter of the words and make the rest of the words lowercase. So INTEGRATED would become Integrated.

A second spanner in the works - I want an exception to a few words such as and, in, a, with.

So the above example would become:

"Integrated Engineering 5 Year (Bsc with a Year in Industry)"

How would I do this in Go? I can code the loop/arrays to manage the change but the actual string conversion is what I struggle with.

Upvotes: 63

Views: 117305

Answers (6)

boug
boug

Reputation: 1887

=== DEPRECATION NOTICE ===
The rule Title uses for word boundaries does not handle Unicode punctuation properly.

There is a function in the built-in strings package called Title.

s := "INTEGRATED ENGINEERING 5 Year (BSC with a Year in Industry)"
fmt.Println(strings.Title(strings.ToLower(s)))

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

Upvotes: 134

Alex Chebotarsky
Alex Chebotarsky

Reputation: 513

If you are like me and don't want to use experimental libraries for this, here's a suggestion of how to achieve similar result with standard library strings.

func ToTitle(str string) string {
    letters := strings.Split(str, "")
    return strings.ToUpper(letters[0]) + strings.Join(letters[1:], "")
}

There might be performance difference between experimental library, since we are creating a slice containing all letters, but for some applications this might be the way to go.

Note: additionally you can use strings.ToLower on the second part of the title to lowercase the rest, for my use case this wasn't necessary.

Upvotes: 0

Thanh Nguyen
Thanh Nguyen

Reputation: 11

Here is how you can write your function.

func toTitle(s string) string {
    return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
}

Upvotes: 0

Saurabh
Saurabh

Reputation: 6970

The below is an alternate to the accepted answer, which is now deprecated:

package main

import (
    "fmt"
    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func main() {
    msg := "INTEGRATED ENGINEERING 5 Year (BSC with a Year in Industry)"
    fmt.Println(cases.Title(language.English, cases.Compact).String(msg))
}

Upvotes: 41

TomiEcio
TomiEcio

Reputation: 69

In Go 1.18 strings.Title() is deprecated.

Here you can read the following to know what to use now

you should use cases.Title instead.

Upvotes: 1

tomasz
tomasz

Reputation: 13082

You can use regular expressions for this task. A \w+ regexp will match all the words, then by using Regexp.ReplaceAllStringFunc you can replace the words with intended content, skipping stop words. In your case, strings.ToLower and strings.Title will be also helpful.

Example:

str := "INTEGRATED ENGINEERING 5 Year (BSC with a Year in Industry)"

// Function replacing words (assuming lower case input)
replace := func(word string) string {
    switch word {
    case "with", "in", "a":
        return word
    }
    return strings.Title(word)
}

r := regexp.MustCompile(`\w+`)
str = r.ReplaceAllStringFunc(strings.ToLower(str), replace)

fmt.Println(str)

// Output:
// Integrated Engineering 5 Year (Bsc with a Year in Industry)

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

You can easily adapt this to your array of strings.

Upvotes: 16

Related Questions