为了账号安全,请及时绑定邮箱和手机立即绑定

拆分字符串时,如何在输出中包含运算符?

拆分字符串时,如何在输出中包含运算符?

Go
慕沐林林 2021-10-11 13:26:46
昨天我问了这个关于在 python 中拆分字符串的问题。从那以后,我决定用 Go 来做这个项目。我有以下几点:input := "house-width + 3 - y ^ (5 * house length)"s := regexp.MustCompile(" ([+-/*^]) ").Split(input, -1)log.Println(s)  //  [house-width 3 y (5 house length)]如何在此输出中包含运算符?例如,我想要以下输出:['house-width', '+', '3', '-', 'y', '^', '(5', '*', 'house length)']编辑:为了澄清我正在拆分以空格分隔的运算符,而不仅仅是运算符。运算符的两端必须有一个空格,以将其与破折号/连字符区分开来。如果需要,请参阅我链接到的原始 python 问题以进行澄清。
查看完整描述

3 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

您可以使用regexp.Split()(就像您所做的那样)获取表达式的操作数,并且可以使用regexp.FindAllString().


通过这样做,您将拥有 2 个单独的[]string切片,如果您希望将结果合并为一个切片,则可以合并这 2 个[]string切片。


input := "house-width + 3 - y ^ (5 * house length)"


r := regexp.MustCompile(`\s([+\-/*^])\s`)


s1 := r.Split(input, -1)

s2 := r.FindAllString(input, -1)


fmt.Printf("%q\n", s1)

fmt.Printf("%q\n", s2)


all := make([]string, len(s1)+len(s2))

for i := range s1 {

    all[i*2] = s1[i]

    if i < len(s2) {

        all[i*2+1] = s2[i]

    }

}

fmt.Printf("%q\n", all)

输出(在Go Playground上试试):


["house-width" "3" "y" "(5" "house length)"]

[" + " " - " " ^ " " * "]

["house-width" " + " "3" " - " "y" " ^ " "(5" " * " "house length)"]

笔记:


如果要修剪运算符中的空格,可以使用该strings.TrimSpace()函数:


for i, v := range s2 {

    all[i*2+1] = strings.TrimSpace(v)

}

fmt.Printf("%q\n", all)

输出:


["house-width" "+" "3" "-" "y" "^" "(5" "*" "house length)"]


查看完整回答
反对 回复 2021-10-11
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

如果您打算在之后解析表达式,则必须进行一些更改:


包括括号作为词素

你不能让空格和破折号都是有效的标识符字符,因为例如在两者- y之间3并且^将是一个有效的标识符。

完成后,您可以使用简单的线性迭代来对字符串进行词法分析:


package main


import (

    "bytes"

    "fmt"

)


func main() {


    input := `house width + 3 - y ^ (5 * house length)`

    buffr := bytes.NewBuffer(nil)

    outpt := make([]string, 0)


    for _, r := range input {

        if r == '+' || r == '-' || r == '*' || r == '/' || r == '^' || r == '(' || r == ')' || (r >= '0' && r <= '9') {

            bs := bytes.TrimSpace(buffr.Bytes())

            if len(bs) > 0 {

                outpt = append(outpt, (string)(bs))

            }

            outpt = append(outpt, (string)(r))

            buffr.Reset()

        } else {

            buffr.WriteRune(r)

        }

    }


    fmt.Printf("%#v\n", outpt)


}

词法分析后,使用 Dijkstra 的分流码算法构建 AST 或直接评估表达式。


查看完整回答
反对 回复 2021-10-11
  • 3 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信