3 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
這是另一個(gè)基于機(jī)器可讀輸出的解決方案。gpg --list-keys --with-colons
它仍然是一個(gè)緩慢的解決方案,但易于編寫,易于更新,不使用正則表達(dá)式。
一個(gè)聰明的人可以帶來一個(gè)更快的解決方案,而不會(huì)增加一個(gè)瘋狂的復(fù)雜性墻。(只需循環(huán)遍歷字符串,直到捕獲字符串,直到<>)
這是基于一個(gè)簡(jiǎn)單的csv閱讀器,因此您可以將其插入到命令的輸出流中。執(zhí)行實(shí)例,或其他任何內(nèi)容。
最大的優(yōu)點(diǎn)是它不需要緩沖內(nèi)存中的整個(gè)數(shù)據(jù),它可以流解碼。
package main
import (
"encoding/csv"
"fmt"
"io"
"regexp"
"strings"
)
func main() {
fmt.Printf("%#v\n", extractEmailsCSV(csvInput))
}
var uid = regexp.MustCompile(`\<(.*?)\>`)
func extractEmailsRegexp(input string) (out []string) {
submatchall := uid.FindAllString(input, -1)
for _, element := range submatchall {
element = strings.Trim(element, "<")
element = strings.Trim(element, ">")
out = append(out, element)
}
return
}
func extractEmailsCSV(input string) (out []string) {
r := strings.NewReader(input)
csv := csv.NewReader(r)
csv.Comma = ':'
csv.ReuseRecord = true
csv.FieldsPerRecord = -1
for {
records, err := csv.Read()
if err == io.EOF {
break
} else if err != nil {
panic(err)
}
if len(records) < 10 {
continue
}
r := records[9]
if strings.Contains(r, "@") {
begin := strings.Index(r, "<")
end := strings.Index(r, ">")
if begin+end > 0 {
out = append(out, r[begin+1:end])
}
}
}
return
}
var regexpInput = `
pub rsa3072 2021-08-03 [SC] [expires: 2023-08-03]
07C47E284765D5593171C18F00B11D51A071CB55
uid [ultimate] user1 <user1@example.com>
sub rsa3072 2021-08-03 [E] [expires: 2023-08-03]
pub rsa3072 2021-08-04 [SC]
37709ABD4D96324AB8CBFC3B441812AFBCE7A013
uid [ultimate] user2 <user2@example.com>
sub rsa3072 2021-08-04 [E]
`
var csvInput = `pub:u:1024:17:51FF9A17136C5B87:1999-04-24::59:-:Tony Nelson <tnelson@techie.com>:
uid:u::::::::Tony Nelson <tnelson@conceptech.com>:
`
我們沒有完全相同的基準(zhǔn)測(cè)試設(shè)置,但無論如何。如果您認(rèn)為它膨脹了比較,請(qǐng)隨時(shí)提供更好的工作臺(tái)設(shè)置。
這是基準(zhǔn)測(cè)試設(shè)置
package main
import (
"strings"
"testing"
)
func BenchmarkCSV_1(b *testing.B) {
input := strings.Repeat(csvInput, 1)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsCSV(input)
}
}
func BenchmarkRegExp_1(b *testing.B) {
input := strings.Repeat(regexpInput, 1)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsRegexp(input)
}
}
func BenchmarkCSV_10(b *testing.B) {
input := strings.Repeat(csvInput, 10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsCSV(input)
}
}
func BenchmarkRegExp_10(b *testing.B) {
input := strings.Repeat(regexpInput, 10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsRegexp(input)
}
}
func BenchmarkCSV_100(b *testing.B) {
input := strings.Repeat(csvInput, 100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsCSV(input)
}
}
func BenchmarkRegExp_100(b *testing.B) {
input := strings.Repeat(regexpInput, 100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = extractEmailsRegexp(input)
}
}
這是結(jié)果
BenchmarkCSV_1
BenchmarkCSV_1-4 242736 4200 ns/op 5072 B/op 18 allocs/op
BenchmarkRegExp_1
BenchmarkRegExp_1-4 252232 4466 ns/op 400 B/op 9 allocs/op
BenchmarkCSV_10
BenchmarkCSV_10-4 68257 17335 ns/op 7184 B/op 40 allocs/op
BenchmarkRegExp_10
BenchmarkRegExp_10-4 29871 39947 ns/op 3414 B/op 68 allocs/op
BenchmarkCSV_100
BenchmarkCSV_100-4 7538 141609 ns/op 25872 B/op 223 allocs/op
BenchmarkRegExp_100
BenchmarkRegExp_100-4 1726 674718 ns/op 37858 B/op 615 allocs/op
在原始速度和分配方面,正則表達(dá)式在小數(shù)據(jù)集上更好,盡管只要有一點(diǎn)點(diǎn)數(shù)據(jù),正則表達(dá)式就會(huì)變慢并且分配更多因素。
另見 https://pkg.go.dev/testing
我的結(jié)論是,不要使用正則表達(dá)式...此外,優(yōu)化正則表達(dá)式即使不是不可能,也是困難的,因?yàn)閮?yōu)化算法以解析某些文本輸入是可行的,如果不是那么容易。
總而言之,如果沒有一個(gè)深思熟慮的程序員來驅(qū)動(dòng)它,即使是最快和最好的運(yùn)行時(shí)也算不了什么。

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊
所以我更新了正則表達(dá)式...但是由于正在研究在線模擬器,我真的很驚訝。為什么正則表達(dá)式不能在所有語言中都一樣工作...(?<=\<)(.*?)(?=\>)
func parseOutput(outs []byte, GPG *GPGList) {
var uid = regexp.MustCompile(`\<(.*?)\>`)
submatchall := uid.FindAllString(string(outs), -1)
for _, element := range submatchall {
element = strings.Trim(element, "<")
element = strings.Trim(element, ">")
fmt.Println(element)
}
}

TA貢獻(xiàn)1835條經(jīng)驗(yàn) 獲得超7個(gè)贊
正則表達(dá)式包使用 RE2 接受的語法。從 https://github.com/google/re2/wiki/Syntax
(?<=re) 后的文本匹配 re (不支持)
因此,錯(cuò)誤消息:
解析正則表達(dá)式時(shí)出錯(cuò): 無效或不受支持的 Perl 語法:
(?<
在線模擬器可能正在測(cè)試不同的正則表達(dá)式語法。您將需要找到替代的正則表達(dá)式編碼或不同的正則表達(dá)式包。
您可以嘗試的替代編碼是(游樂場(chǎng))。這很簡(jiǎn)單,可能與您的原始意圖不符。\<([^\>]*)\>
- 3 回答
- 0 關(guān)注
- 158 瀏覽
添加回答
舉報(bào)