Golang从符文转换为字符串

use*_*708 24 string unicode parsing go rune

我有以下代码,它应该rune投入一个string并打印出来.但是,我在打印时会得到未定义的字符.我无法弄清楚bug的位置:

package main

import (
    "fmt"
    "strconv"
    "strings"
    "text/scanner"
)

func main() {
    var b scanner.Scanner
    const a = `a`
    b.Init(strings.NewReader(a))
    c := b.Scan()
    fmt.Println(strconv.QuoteRune(c))
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 20

那是因为你曾经Scanner.Scan()读过一篇文章,rune但它确实做了别的事情.Scanner.Scan()可用于读取由位掩码控制的特殊标记的令牌rune标记Scanner.Mode,并从text/scanner包中返回特殊常量,而不是读取符文本身.

改为阅读一次rune使用Scanner.Next():

c := b.Next()
fmt.Println(c, string(c), strconv.QuoteRune(c))
Run Code Online (Sandbox Code Playgroud)

输出:

97 a 'a'
Run Code Online (Sandbox Code Playgroud)

如果您只想将单个转换runestring,请使用简单的类型转换.rune是别名int32,并将整数转换为string:

将有符号或无符号整数值转换为字符串类型会生成包含整数的UTF-8表示形式的字符串.

所以:

r := rune('a')
fmt.Println(r, string(r))
Run Code Online (Sandbox Code Playgroud)

输出:

97 a
Run Code Online (Sandbox Code Playgroud)

要循环遍历string值的符文,您只需使用for ... range构造:

for i, r := range "abc" {
    fmt.Printf("%d - %c (%v)\n", i, r, r)
}
Run Code Online (Sandbox Code Playgroud)

输出:

0 - a (97)
1 - b (98)
2 - c (99)
Run Code Online (Sandbox Code Playgroud)

或者您只需将string值转换为[]rune:

fmt.Println([]rune("abc")) // Output: [97 98 99]
Run Code Online (Sandbox Code Playgroud)

还有utf8.DecodeRuneInString().

试试Go Playground上的例子.

注意:

您的原始代码(使用Scanner.Scan())的工作方式如下:

  1. 你调用了Scanner.Init()哪个将Mode(b.Mode)设置为scanner.GoTokens.
  2. 调用Scanner.Scan()input(from "a")返回scanner.Ident是因为"a"是一个有效的Go标识符:

    c := b.Scan()
    if c == scanner.Ident {
        fmt.Println("Identifier:", b.TokenText())
    }
    
    // Output: "Identifier: a"
    
    Run Code Online (Sandbox Code Playgroud)