Reputation: 791
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
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
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
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
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
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
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