猿问

通过正则表达式拆分输入字符串

如何在 Go 中通过正则表达式拆分下面的输入字符串?字符串示例:


我知道如何按点拆分,但如何避免在引号中拆分?


"a.b.c.d" -> ["a", "b", "c", "d"]

"a."b.c".d" -> ["a", "b.c", "d"]

"a.'b.c'.d" -> ["a", "b.c", "d"]


元芳怎么了
浏览 120回答 3
3回答

吃鸡游戏

这是另一个选项,它的正则表达式不那么复杂。它使用垃圾桶技巧。所以真正的数据在(第一和第二)捕获组上。它甚至适用于像这样的嵌套引号:"a.'b.c'.d.e."f.g.h""只要没有 2 级或更多级别的递归(如此处:"a.'b."c.d"'",引号内引号内引号)。正则表达式是这样的:^"|['"](\w+(?:\.\w+)*)['"]|(\w+)和代码:package mainimport (    "regexp"    "fmt")func main() {    var re = regexp.MustCompile(`^"|['"](\w+(?:\.\w+)*)['"]|(\w+)`)    var str = `"a.'b.c'.d.e."f.g.h""`    result := re.FindAllStringSubmatch(str, -1)    for _, m := range result {        if (m[1] != "" || m[2] != "") {            fmt.Print(m[1] + m[2] + "\n")        }    }}输入:"a.'b.c'.d.e."f.g.h""输出:ab.cdef.g.h

Helenr

匹配平衡定界符对于正则表达式来说是一个复杂的问题,除非你使用类似Go pcre package 的东西。相反,可以修改Go CSV 解析器。将其配置为用作.分隔符、惰性引号(CSV 引号为')和可变长度记录。package mainimport (    "encoding/csv"    "fmt"    "io"    "log"    "strings")func main() {    lines := `a.b.c.da.\"b.c\".da.'b.c'.d`    csv := csv.NewReader(strings.NewReader(lines))    csv.Comma = '.'    csv.LazyQuotes = true    csv.FieldsPerRecord = -1    for {        record, err := csv.Read()        if err == io.EOF {            break        }        if err != nil {            log.Fatal(err)        }        fmt.Printf("%#v\n", record)    }}

BIG阳

由于 go 不支持否定前瞻,我认为找到与.您要拆分的正则表达式相匹配的正则表达式并不容易/可能。相反,您可以匹配周围的文本并仅适当地捕获:所以正则表达式本身有点难看,但这是细分(忽略转义字符):(\'[^.'"]+(?:\.[^.'"]+)+\')|(\"[^.'"]+(?:\.[^.'"]+)+\")|(?:([^.'"]+)\.?)|(?:\.([^.'\"]+))此正则表达式匹配四种情况,并捕获这些匹配的某些子集:(\'[^.'"]+(?:\.[^.'"]+)+\')- 匹配和捕获单引号文本\'-'逐字匹配[^.'"]+- 匹配非行号和非句点的序列(?:\.[^.'"]+)+- 匹配句点后跟一系列非引号和非句点,根据需要重复多次。没有被捕获。\'-'逐字匹配(\"[^.'"]+(?:\.[^.'"]+)+\")- 匹配和捕获双引号文本与上面相同,但带有双引号(?:([^.'"]+)\.?)- 匹配由可选 开始的文本.,不捕获.([^.'"]+)- 匹配和捕获非报价和非句点的序列\.?- 可选择匹配一个句点(可选择捕获最后一位分隔文本)(?:\.([^.'"]+))- 匹配前面有 a 的文本.,不捕获.与上面相同,但句点在捕获组之前,也是非可选的转储捕获的示例代码:package mainimport (    "fmt"    "regexp")func main() {    re := regexp.MustCompile("('[^.'\"]+(?:\\.[^.'\"]+)+')|(\"[^.'\"]+(?:\\.[^.'\"]+)+\")|(?:([^.'\"]+)\\.?)|(?:\\.([^.'\"]+))")    txt := "a.b.c.'d.e'"    result:= re.FindAllStringSubmatch(txt, -1)    for k, v := range result {        fmt.Printf("%d. %s\n", k, v)    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答