3 回答

TA貢獻1829條經驗 獲得超7個贊
這是另一個選項,它的正則表達式不那么復雜。它使用垃圾桶技巧。所以真正的數據在(第一和第二)捕獲組上。
它甚至適用于像這樣的嵌套引號:"a.'b.c'.d.e."f.g.h""
只要沒有 2 級或更多級別的遞歸(如此處:"a.'b."c.d"'"
,引號內引號內引號)。
正則表達式是這樣的:^"|['"](\w+(?:\.\w+)*)['"]|(\w+)
和代碼:
package main
import (
? ? "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""
輸出:
a
b.c
d
e
f.g.h

TA貢獻1780條經驗 獲得超4個贊
匹配平衡定界符對于正則表達式來說是一個復雜的問題,除非你使用類似Go pcre package 的東西。
相反,可以修改Go CSV 解析器。將其配置為用作.
分隔符、惰性引號(CSV 引號為'
)和可變長度記錄。
package main
import (
? ? "encoding/csv"
? ? "fmt"
? ? "io"
? ? "log"
? ? "strings"
)
func main() {
? ? lines := `a.b.c.d
a.\"b.c\".d
a.'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)
? ? }
}

TA貢獻1859條經驗 獲得超6個贊
由于 go 不支持否定前瞻,我認為找到與.
您要拆分的正則表達式相匹配的正則表達式并不容易/可能。相反,您可以匹配周圍的文本并僅適當地捕獲:
所以正則表達式本身有點難看,但這是細分(忽略轉義字符):
(\'[^.'"]+(?:\.[^.'"]+)+\')|(\"[^.'"]+(?:\.[^.'"]+)+\")|(?:([^.'"]+)\.?)|(?:\.([^.'\"]+))
此正則表達式匹配四種情況,并捕獲這些匹配的某些子集:
(\'[^.'"]+(?:\.[^.'"]+)+\')
- 匹配和捕獲單引號文本\'
-'
逐字匹配[^.'"]+
- 匹配非行號和非句點的序列(?:\.[^.'"]+)+
- 匹配句點后跟一系列非引號和非句點,根據需要重復多次。沒有被捕獲。\'
-'
逐字匹配(\"[^.'"]+(?:\.[^.'"]+)+\")
- 匹配和捕獲雙引號文本與上面相同,但帶有雙引號
(?:([^.'"]+)\.?)
- 匹配由可選 開始的文本.
,不捕獲.
([^.'"]+)
- 匹配和捕獲非報價和非句點的序列\.?
- 可選擇匹配一個句點(可選擇捕獲最后一位分隔文本)(?:\.([^.'"]+))
- 匹配前面有 a 的文本.
,不捕獲.
與上面相同,但句點在捕獲組之前,也是非可選的
轉儲捕獲的示例代碼:
package main
import (
"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)
}
}
- 3 回答
- 0 關注
- 173 瀏覽
添加回答
舉報