56

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.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Conor
  • 721
  • 1
  • 6
  • 18

5 Answers5

132

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

blackgreen
  • 34,072
  • 23
  • 111
  • 129
boug
  • 1,859
  • 1
  • 13
  • 13
16

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.

tomasz
  • 12,574
  • 4
  • 43
  • 54
  • Use \pL (unicode letter) instead of \w (ascii only) for free text. Your solution gives "Manager Of Two CaféS in QuéBec"). Also, know that title is deprecated (see @TomiEcio's answer). – Betamos Jul 03 '22 at 00:43
15

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))
}
Saurabh
  • 5,176
  • 4
  • 32
  • 46
0

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.

TomiEcio
  • 59
  • 6
-28

Well you didn't specify the language you're using, so I'll give you a general answer. You have an array with a bunch of strings in it. First I'd make the entire string lower case, then just go through each character in the string (capitalize the first one, rest stay lower case). At this point you need to look for the space, this will help you divide up the words in each string. The first character after finding a space is obviously a different word and should be capitalized. You can verify the next word isn't and in with Or a as well.

I'm not at a computer so I can't give to a specific example, but I hope this gets to in the right direction at least

Rickybobby
  • 245
  • 1
  • 13
  • 9
    He's using Go. Tag is the main indicator here, although it was also mentioned in the question. – tomasz Nov 13 '15 at 15:48
  • Even thougth, the layer don't see clearly to get the language is Go, but the idea is correct. – ElapsedSoul Dec 09 '21 at 01:25
  • Second, the point of this question I think has nothing to do with which language is used. And from "I'm not at a computer", we can get the layer was using mobile, which it's acceptable for the little mistake , so I up the answer for the layer's enthusiasm and the correct idea. – ElapsedSoul Dec 09 '21 at 01:31