Editor PHP Baicao hari ini memperkenalkan cara menggunakan ungkapan biasa untuk memadankan baris lengkap yang mengandungi "ralat" atau "amaran" (tidak peka huruf besar-besaran) dalam golang. Ungkapan biasa ialah alat padanan corak teks yang berkuasa yang boleh membantu kami mencari kandungan yang sepadan dengan corak tertentu dalam rentetan. Dalam golang, menggunakan ungkapan biasa memerlukan pengenalan pakej regexp dan menggunakan fungsi Compile untuk menyusun ungkapan biasa. Seterusnya, kami akan memperkenalkan secara terperinci cara menggunakan ungkapan biasa untuk padanan baris dalam golang.
Saya ingin mencetak baris lengkap setiap baris dalam fail log yang mengandungi amaran atau ralat (case insensitive) kepada pengguna.
DIANYA:
[01-17|18:53:38.179] info server/server.go:381 this would be skipped [01-17|18:53:38.280] info server/server.go:620 this also [01-17|18:53:41.180] warn server/server.go:388 something is warned, so show this [01-17|18:53:41.394] warn server/server.go:188 something reported an ->error<- [01-17|18:53:41.395] error server/server.go:191 blabla [01-17|18:53:41.395] debug server/server.go:196 obviously skipped [01-17|18:53:41.395] debug server/server.go:196 this debug contains an ->error<- so match this [01-17|18:53:41.395] warn server/server.go:198 you get the idea
Saya mahu:
[01-17|18:53:41.180] warn server/server.go:388 something is warned, so show this [01-17|18:53:41.394] warn server/server.go:188 something reported an ->error<- [01-17|18:53:41.395] error server/server.go:191 blabla [01-17|18:53:41.395] debug server/server.go:196 this debug contains an ->error<- so match this [01-17|18:53:41.395] warn server/server.go:198 you get the idea
Saya bermula dengan tidak bersalah
errorregex := regexp.mustcompile(`(?is)error|warn`)
Ia hanya akan mencetak (dari larian yang berbeza, mungkin tidak sepadan dengan contoh di atas tepat)
warn error
Kemudian saya fikir saya perlu menukarnya supaya lebih sepadan:
errorRegEx := regexp.MustCompile(`(?is).*error.*|.*warn.*`)
Tetapi ini tidak mencetak apa-apa pun
Bagaimana untuk mendapatkan talian lengkap dan semua baris yang amaran atau ralat (tidak sensitif huruf besar) akan sepadan?
ps: Ini tidak sama dengan baris padanan regex yang dicadangkan yang mengandungi rentetan, kerana ini adalah soalan khusus untuk bahasa go
, yang nampaknya tidak menggunakan enjin standard yang sama.
Memandangkan soalan itu telah ditandakan sebagai penipu, komen op adalah seperti berikut.
Soalan ini ditandakan sebagai pendua, dan siaran yang dipautkan mempunyai banyak jawapan yang boleh kita gunakan untuk cuba mengumpulkan jawapan kepada soalan OP, tetapi ia masih tidak lengkap kerana jawapannya nampaknya berkaitan dengan pcre and go menggunakan re2.
var logs = ` [01-17|18:53:38.179] info server/server.go:381 this would be skipped [01-17|18:53:38.280] info server/server.go:620 this also [01-17|18:53:41.180] warn server/server.go:388 something is warned, so show this [01-17|18:53:41.394] warn server/server.go:188 something reported an ->error<- [01-17|18:53:41.395] error server/server.go:191 blabla [01-17|18:53:41.395] debug server/server.go:196 obviously skipped [01-17|18:53:41.395] debug server/server.go:196 this debug contains an ->error<- so match this [01-17|18:53:41.395] warn server/server.go:198 you get the idea ` func init() { logs = strings.trimspace(logs) }
Pertama sekali, saya tidak faham mengapa ini tidak mencetak apa-apa untuk op :
Kemudian saya fikir saya perlu menukarnya supaya lebih sepadan:
errorregex := regexp.mustcompile(`(?is).*error.*|.*warn.*`)
Tetapi ini tidak mencetak apa-apa pun
Sebab semuanya perlu dicetak :
fmt.println("original regexp:") reoriginal := regexp.mustcompile(`(?is).*error.*|.*warn.*`) lines := reoriginal.findallstring(logs, -1) fmt.println("match\t\tentry") fmt.println("=====\t\t=====") for i, line := range lines { fmt.printf("%d\t\t%q\n", i+1, line) }
original regexp: match entry ===== ===== 1 "[01-17|18:53:38.179] info server/server.go:381 this would be skipped\n[01-17|18:53:38.280] info server/server.go:620 this also\n[01-17|18:53:41.180] warn server/server.go:388 something is warned, so show this\n[01-17|18:53:41.394] warn server/server.go:188 something reported an ->error<-\n[01-17|18:53:41.395] error server/server.go:191 blabla\n[01-17|18:53:41.395] debug server/server.go:196 obviously skipped\n[01-17|18:53:41.395] debug server/server.go:196 this debug contains an ->error<- so match this\n[01-17|18:53:41.395] warn server/server.go:198 you get the idea"
(?is)...
中的 s
标志表示将换行符与点匹配 (.
)^1,并且因为您的星星 (*
) adalah tamak^2, jika "ralat" atau "amaran" ditemui, ia akan memadankan segala-galanya dalam keseluruhan rentetan.
Penyelesaian sebenar adalah untuk tidak memadankan 'n' dengan mata - tanggalkan bendera s
dan anda mendapat hasil yang anda inginkan:
fmt.println("whole text:") rewholetext := regexp.mustcompile(`(?i).*error.*|.*warn.*`) lines = rewholetext.findallstring(logs, -1) fmt.println("match\t\tentry") fmt.println("=====\t\t=====") for i, line := range lines { fmt.printf("%d\t\t%q\n", i+1, line) }
whole text: match entry ===== ===== 1 "[01-17|18:53:41.180] warn server/server.go:388 something is warned, so show this" 2 "[01-17|18:53:41.394] warn server/server.go:188 something reported an ->error<-" 3 "[01-17|18:53:41.395] error server/server.go:191 blabla" 4 "[01-17|18:53:41.395] debug server/server.go:196 this debug contains an ->error<- so match this" 5 "[01-17|18:53:41.395] warn server/server.go:198 you get the idea"
Kini kami memadankan antara kejadian "n" (baris yang sah) kerana kami menggunakan borang all
, yang hanya mencari tidak bertindih padanan:
Jika "semua" hadir, rutin akan memadankan padanan tidak bertindih berturut-turut bagi keseluruhan ungkapan. ^3< /a>
Kami mendapat garisan yang lengkap dan jelas.
Anda boleh mengetatkan sedikit regex ini:
`(?i).*(?:error|warn).*` // "anything before either "error" or "warn" and anything after (for a line)"
(?:...)
ialah kumpulan bukan menangkap ^1 kerana anda nampaknya tidak mengambil berat tentang kejadian individu "ralat" atau "amaran" dalam setiap perlawanan.
Selain itu, saya masih ingin menunjukkan bahawa pemisahan mengikut baris sebelum cuba memadankan memberikan anda lebih kawalan/ketepatan dan menjadikan ungkapan biasa sangat mudah untuk dihuraikan:
r := strings.newreader(logs) scanner := bufio.newscanner(r) fmt.println("line-by-line:") reline := regexp.mustcompile(`(?i)error|warn`) fmt.println("match\tline\tentry") fmt.println("=====\t====\t=====") var matchno, lineno, match = 1, 1, "" for scanner.scan() { line := scanner.text() match = reline.findstring(line) if match != "" { fmt.printf("%d\t%d\t%q\n", matchno, lineno, line) matchno++ } lineno++ }
Line-by-line: match line entry ===== ==== ===== 1 3 "[01-17|18:53:41.180] Warn server/server.go:388 Something is warned, so show this" 2 4 "[01-17|18:53:41.394] warn server/server.go:188 Something reported an ->error<-" 3 5 "[01-17|18:53:41.395] Error server/server.go:191 Blabla" 4 7 "[01-17|18:53:41.395] DEBUG server/server.go:196 This debug contains an ->error<- so match this" 5 8 "[01-17|18:53:41.395] WARN server/server.go:198 You get the idea"
Ketiga-tiga contoh terletak di taman permainan ini.
Atas ialah kandungan terperinci Ungkapan biasa dengan golang untuk memadankan baris lengkap yang mengandungi 'ralat' atau 'amaran' (tidak sensitif huruf besar-besaran). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!