亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過正則表達式拆分輸入字符串

通過正則表達式拆分輸入字符串

Go
元芳怎么了 2023-05-08 14:39:48
如何在 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"]
查看完整描述

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



查看完整回答
反對 回復 2023-05-08
?
Helenr

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)

? ? }

}


查看完整回答
反對 回復 2023-05-08
?
BIG陽

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)

    }

}


查看完整回答
反對 回復 2023-05-08
  • 3 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號