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

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

如何在 Go 中模擬負向后視

如何在 Go 中模擬負向后視

Go
慕村9548890 2021-11-22 10:42:50
我正在嘗試編寫一個可以提取命令的正則表達式,這是到目前為止我使用否定的lookbehind斷言所得到的:\b(?<![@#\/])\w.*所以輸入:/msg @nickname #channel foo bar baz/foo #channel @nickname foo bar baz foo bar bazfoo bar baz每次都被提取。請參閱工作示例 https://regex101.com/r/lF9aG7/3然而,在 Go 中這不會編譯http://play.golang.org/p/gkkVZgScS_它拋出:panic: regexp: Compile(`\b(?<![@#\/])\w.*`): error parsing regexp: invalid or unsupported Perl syntax: `(?<`我做了一些研究并意識到語言中不支持負向后視來保證 O(n) 時間。我怎樣才能重寫這個正則表達式,讓它在沒有負面回顧的情況下做同樣的事情?
查看完整描述

2 回答

?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

由于在否定的回顧中,您只使用了一個簡單的字符集;您可以用否定字符集替換它:


\b[^@#/]\w.*

如果在字符串的開頭允許,則使用^錨點:


(?:^|[^@#\/])\b\w.*

根據您問題中 Go 游樂場鏈接中的示例,我認為您希望過濾掉所有以[#@/]. 您可以使用一個filter函數:


func Filter(vs []string, f func(string) bool) []string {

    vsf := make([]string, 0)

    for _, v := range vs {

        if f(v) {

            vsf = append(vsf, v)

        }

    }

    return vsf

}

和一個Process函數,它利用了上面的過濾器:


func Process(inp string) string {

    t := strings.Split(inp, " ")

    t = Filter(t, func(x string) bool {

        return strings.Index(x, "#") != 0 &&

            strings.Index(x, "@") != 0 &&

            strings.Index(x, "/") != 0

    })

    return strings.Join(t, " ")

}

它可以在操場上看到http://play.golang.org/p/ntJRNxJTxo


查看完整回答
反對 回復 2021-11-22
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

您實際上可以匹配前面的字符(或行的開頭)并使用組在子表達式中獲取所需的文本。

正則表達式

(?:^|[^@#/])\b(\w+)
  • (?:^|[^@#/])匹配^行首或[^@#/]任何字符,除了@#/

  • \b 斷言單詞開頭的單詞邊界

  • (\w+) 生成子表達式

    • 并匹配\w+任意數量的單詞字符

代碼

cmds := []string{

    `/msg @nickname #channel foo bar baz`,

    `#channel @nickname foo bar baz /foo`,

    `foo bar baz @nickname #channel`,

    `foo bar baz#channel`}


regex := regexp.MustCompile(`(?:^|[^@#/])\b(\w+)`)



// Loop all cmds

for _, cmd := range cmds{

    // Find all matches and subexpressions

    matches := regex.FindAllStringSubmatch(cmd, -1)


    fmt.Printf("`%v` \t==>\n", cmd)


    // Loop all matches

    for n, match := range matches {

        // match[1] holds the text matched by the first subexpression (1st set of parentheses)

        fmt.Printf("\t%v. `%v`\n", n, match[1])

    }

}

輸出


`/msg @nickname #channel foo bar baz`   ==>

    0. `foo`

    1. `bar`

    2. `baz`

`#channel @nickname foo bar baz /foo`   ==>

    0. `foo`

    1. `bar`

    2. `baz`

`foo bar baz @nickname #channel`    ==>

    0. `foo`

    1. `bar`

    2. `baz`

`foo bar baz#channel`   ==>

    0. `foo`

    1. `bar`

    2. `baz`

游樂場

http://play.golang.org/p/AaX9Cg-7Vx


查看完整回答
反對 回復 2021-11-22
  • 2 回答
  • 0 關注
  • 181 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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