昨天我问this question有关在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问题以进行说明。
答案 0 :(得分:1)
您可以使用regexp.Split()
获取表达式的操作数(就像您一样),您可以使用regexp.FindAllString()
获取运算符(分隔符)。
通过执行此操作,您将拥有2个单独的[]string
切片,如果您希望将结果放在一个[]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)"]
答案 1 :(得分:1)
如果您之后计划解析表达式,则必须进行一些更改:
- y
和3
之间的^
将是有效的标识符。完成后,你可以使用一个简单的linear iteration来勒索你的字符串:
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的shunting-yard algorithm来构建AST或直接评估表达式。
答案 2 :(得分:0)
我认为FindAll()可能就是这样。
扩展正则表达式:
\s* # Trim preceding whitespace
( # (1 start), Operator/Non-Operator chars
(?: # Cluster group
\w - # word dash
| - \w # or, dash word
| [^+\-/*^] # or, a non-operator char
)+ # End cluster, do 1 to many times
| # or,
[+\-/*^] # A single simple math operator
) # (1 end)
\s* # Trim trailing whitespace
Go code snippet:
http://play.golang.org/p/bHZ21B6Tzi
package main
import (
"log"
"regexp"
)
func main() {
in := []byte("house-width + 3 - y ^ (5 * house length)")
rr := regexp.MustCompile("\\s*((?:\\w-|-\\w|[^+\\-/*^])+|[+\\-/*^])\\s*")
s := r.FindAll( in, -1 )
for _, ss:=range s{
log.Println(string(ss))
}
}
输出:
house-width
+
3
-
y
^
(5
*
house length)