3 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
這是另一個(gè)選項(xiàng),它的正則表達(dá)式不那么復(fù)雜。它使用垃圾桶技巧。所以真正的數(shù)據(jù)在(第一和第二)捕獲組上。
它甚至適用于像這樣的嵌套引號(hào):"a.'b.c'.d.e."f.g.h""
只要沒有 2 級(jí)或更多級(jí)別的遞歸(如此處:"a.'b."c.d"'"
,引號(hào)內(nèi)引號(hào)內(nèi)引號(hào))。
正則表達(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貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超4個(gè)贊
匹配平衡定界符對于正則表達(dá)式來說是一個(gè)復(fù)雜的問題,除非你使用類似Go pcre package 的東西。
相反,可以修改Go CSV 解析器。將其配置為用作.
分隔符、惰性引號(hào)(CSV 引號(hào)為'
)和可變長度記錄。
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貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
由于 go 不支持否定前瞻,我認(rèn)為找到與.
您要拆分的正則表達(dá)式相匹配的正則表達(dá)式并不容易/可能。相反,您可以匹配周圍的文本并僅適當(dāng)?shù)夭东@:
所以正則表達(dá)式本身有點(diǎn)難看,但這是細(xì)分(忽略轉(zhuǎn)義字符):
(\'[^.'"]+(?:\.[^.'"]+)+\')|(\"[^.'"]+(?:\.[^.'"]+)+\")|(?:([^.'"]+)\.?)|(?:\.([^.'\"]+))
此正則表達(dá)式匹配四種情況,并捕獲這些匹配的某些子集:
(\'[^.'"]+(?:\.[^.'"]+)+\')
- 匹配和捕獲單引號(hào)文本\'
-'
逐字匹配[^.'"]+
- 匹配非行號(hào)和非句點(diǎn)的序列(?:\.[^.'"]+)+
- 匹配句點(diǎn)后跟一系列非引號(hào)和非句點(diǎn),根據(jù)需要重復(fù)多次。沒有被捕獲。\'
-'
逐字匹配(\"[^.'"]+(?:\.[^.'"]+)+\")
- 匹配和捕獲雙引號(hào)文本與上面相同,但帶有雙引號(hào)
(?:([^.'"]+)\.?)
- 匹配由可選 開始的文本.
,不捕獲.
([^.'"]+)
- 匹配和捕獲非報(bào)價(jià)和非句點(diǎn)的序列\.?
- 可選擇匹配一個(gè)句點(diǎn)(可選擇捕獲最后一位分隔文本)(?:\.([^.'"]+))
- 匹配前面有 a 的文本.
,不捕獲.
與上面相同,但句點(diǎn)在捕獲組之前,也是非可選的
轉(zhuǎn)儲(chǔ)捕獲的示例代碼:
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 關(guān)注
- 182 瀏覽
添加回答
舉報(bào)