如何在Go语言中手动将字符串中每个单词的首字母大写?

huangapple go评论81阅读模式
英文:

How to capitalise first letter of each word in a string in go manually?

问题

我正在尝试手动编写一个函数,用于将字符串中每个单词的首字母大写。例如:将 "My dog is cute! I+love+my+dog+4ever" 转换为 "My Dog Is Cute! I+Love+My+Dog+4ever"。如果你需要帮助,我会很乐意帮助你。

func Capitalize(s string) string {
    L := ToLower(s)
    runeL := []rune(L)
    len := len(runeL) - 1
    Lnew := Concat(ToUpper(string(L[0])), string(runeL[1:len]))
    LnewS := []rune(Lnew)
    newstrings := []rune{}
    for i := range LnewS {
        if IsAlpha(string(LnewS[i])) == true {
            newstrings = append(newstrings, LnewS[i])
        } else {
            newstrings = append(newstrings, LnewS[i])
            if LnewS[i+1] == rune(32) {
                newstrings = append(newstrings)
            }
            if IsLower(string(LnewS[i+1:])) {
                LnewS[i+1] = LnewS[i+1] - rune(32)
            }
        }
    }
    return string(newstrings)
}

以上是你要翻译的内容。

英文:

I am trying to write a function manually that capitalises the first letter of each word in a string. For example: "My dog is cute! I+love+my+dog+4ever" to "My Dog Is Cute! I+Love+My+Dog+4ever". I would be glad if you can help me.

func Capitalize(s string) string {
L := ToLower(s)
runeL := []rune(L)
len := len(runeL) - 1
Lnew := Concat(ToUpper(string(L[0])), string(runeL[1:len]))
LnewS := []rune(Lnew)
newstrings := []rune{}
for i := range LnewS {
	if IsAlpha(string(LnewS[i])) == true {
		newstrings = append(newstrings, LnewS[i])
	} else {
		newstrings = append(newstrings, LnewS[i])
		if LnewS[i+1] == rune(32) {
			newstrings = append(newstrings)
		}
		if IsLower(string(LnewS[i+1:])) {
			LnewS[i+1] = LnewS[i+1] - rune(32)
		}
	}
}
return string(newstrings)

}

答案1

得分: 2

如何在Go中手动将字符串中的每个单词的首字母大写?


让我们遵循牛顿的建议,阅读以下内容:

《C程序设计语言》第二版
Brian W. Kernighan和Dennis M. Ritchie

特别是阅读以下内容:

1.5.4 单词计数

该部分介绍了一个关键概念,即状态变量:“变量state记录程序当前是否处于单词中”。


如果我们将这个见解应用到你的问题上,可以得到以下代码:

package main

import (
	"fmt"
	"unicode"
)

func Capitalize(s string) string {
	rs := []rune(s)
	inWord := false
	for i, r := range rs {
		if unicode.IsLetter(r) || unicode.IsNumber(r) {
			if !inWord {
				rs[i] = unicode.ToTitle(r)
			}
			inWord = true
		} else {
			inWord = false
		}
	}
	return string(rs)
}

func main() {
	s := "My dog is cute! I+love+my+dog+4ever"
	fmt.Println(s)
	t := Capitalize(s)
	fmt.Println(t)
}

运行结果:

My dog is cute! I+love+my+dog+4ever
My Dog Is Cute! I+Love+My+Dog+4ever

你可以在以下链接中查看代码运行结果:

https://go.dev/play/p/4QnHIqfGjWy


Unicode: Character Properties, Case Mappings & Names FAQ

Unicode标准中的标题映射是应用于单词中的初始字符的映射。

英文:

> How to capitalise first letter of each word in a string in Go
> manually?


> In a letter to Robert Hooke in 1675, Isaac Newton made his most famous statement: “If I have seen further it is by standing on the shoulders of Giants”.

Let's follow Newton's advice and read,

The C Programming Language, Second Edition
Brian W. Kernighan and Dennis M. Ritchie

In particular, read,

1.5.4 Word Counting

The section introduces a key concept, state variables: "The variable state records whether the program is currently in a word or not."


If we apply that insight to your problem then we get something like this,

package main

import (
	"fmt"
	"unicode"
)

func Capitalize(s string) string {
	rs := []rune(s)
	inWord := false
	for i, r := range rs {
		if unicode.IsLetter(r) || unicode.IsNumber(r) {
			if !inWord {
				rs[i] = unicode.ToTitle(r)
			}
			inWord = true
		} else {
			inWord = false
		}
	}
	return string(rs)
}

func main() {
	s := "My dog is cute! I+love+my+dog+4ever"
	fmt.Println(s)
	t := Capitalize(s)
	fmt.Println(t)
}

https://go.dev/play/p/4QnHIqfGjWy

My dog is cute! I+love+my+dog+4ever
My Dog Is Cute! I+Love+My+Dog+4ever

> [Unicode: Character Properties, Case Mappings & Names FAQ](
> https://unicode.org/faq/casemap_charprop.html)
>
> The titlecase mapping in the Unicode Standard is the mapping applied to the initial character in a word.

答案2

得分: 1

你可以使用strings包中的title函数来将每个单词的首字母大写。下面是一个示例:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)


func main() {
    var strInput string
    fmt.Println("输入一个字符串")
    scanner := bufio.NewScanner(os.Stdin)
    if scanner.Scan() {
        strInput = scanner.Text()
    }

    res := strings.Title(strInput)
    fmt.Println(res)
}

如果你想手动实现,可以编写一个算法:

  • 检查字符串的每个索引
  • 如果一个索引是第一个索引,或者它是一个空格后面的字母,将该索引的字母改为大写,这样就可以实现。
英文:

You can use the strings package with its title function to capitalize first letter of each word. An example of it can be seen below.

package main

import (
    "bufio"
    "fmt"
    "os"
	"strings"
)


func main() {
	var strInput string
	fmt.Println("Enter a string")
	scanner := bufio.NewScanner(os.Stdin)
    if scanner.Scan() {
        strInput = scanner.Text()
    }

    res := strings.Title(strInput)
    fmt.Println(res)
}

If you wanna do it manually, write an algorithm where

  • Checks the entire index of the string
  • If an index is the first index or it's an alphabet after a space, change that index alphabet into uppercase, and it should work

答案3

得分: 0

strings.Title()已被弃用。建议您改用golang.org/x/text/cases。然而,结果并不会产生期望的输出。

cases.Title示例

在终端中运行以下命令...

go get golang.org/x/text

然后,您可以像这样将字符串中的每个单词首字母大写...

package main

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

func main() {
    input := "My dog is cute! I+love+my+dog+4ever"
    output := cases.Title(language.English).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

结果

 input=My dog is cute! I+love+my+dog+4ever
output=My Dog Is Cute! I+Love+My+Dog+4Ever
                                      ^
OP想要'4ever'而不是'4Ever'

cases.Title注意事项1

这也会将所有大写单词转换为只有首字母大写。例如,USA将变为Usa。您需要传递cases.NoLower来避免这种行为。

func main() {
    input := "the USA"
    output := cases.Title(language.English, cases.NoLower).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

// 结果 = "The USA"

cases.Title注意事项2

cases.Title无法很好地处理缩写的英语序数词。例如,10th将被转换为10Th3rd将被转换为3Rd

英文:

strings.Title() has been deprecated. It is recommended that you use golang.org/x/text/cases instead. However, the results do not produce the desired output by the OP.

cases.Title Example

Run the following command in your terminal...

go get golang.org/x/text

Then you can capitalize each word in a string like this...

package main

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

func main() {
    input := "My dog is cute! I+love+my+dog+4ever"
    output := cases.Title(language.English).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

Result

 input=My dog is cute! I+love+my+dog+4ever
output=My Dog Is Cute! I+Love+My+Dog+4Ever
                                      ^
OP wants '4ever' not '4Ever'

cases.Title Note 1

This will also turn all uppercase words to only have the first letter uppercase. E.g. USA will become Usa. You will need to pass cases.NoLower to void this behavior.

func main() {
    input := "the USA"
    output := cases.Title(language.English, cases.NoLower).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

// Result = "The USA"

cases.Title Note 2

cases.Title does not handle abbreviated English ordinal numbers well. For example, 10th will be transformed to 10Th and 3rd will be transformed to 3Rd.

huangapple
  • 本文由 发表于 2021年12月9日 08:47:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/70283464.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定