Maison  >  Article  >  développement back-end  >  Expression régulière avec golang pour correspondre aux lignes complètes contenant « erreur » ou « avertissement » (insensible à la casse)

Expression régulière avec golang pour correspondre aux lignes complètes contenant « erreur » ou « avertissement » (insensible à la casse)

王林
王林avant
2024-02-13 08:21:10392parcourir

正则表达式与 golang 匹配包含“错误”或“警告”(不区分大小写)的完整行

L'éditeur PHP Baicao présente aujourd'hui comment utiliser des expressions régulières pour faire correspondre des lignes complètes contenant "erreur" ou "avertissement" (insensible à la casse) en golang. Les expressions régulières sont un puissant outil de correspondance de modèles de texte qui peut nous aider à trouver du contenu qui correspond à un modèle spécifique dans une chaîne. En Golang, l'utilisation d'expressions régulières nécessite l'introduction du package regexp et l'utilisation de la fonction Compile pour compiler l'expression régulière. Ensuite, nous présenterons en détail comment utiliser les expressions régulières pour la correspondance de lignes dans Golang.

Contenu de la question

Je souhaite imprimer la ligne complète de chaque ligne du fichier journal qui contient un avertissement ou une erreur (insensible à la casse) à l'utilisateur.

CONTENU QUE :

[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

Je veux :

[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

J'ai commencé innocemment

errorregex := regexp.mustcompile(`(?is)error|warn`)

Il s'imprimera simplement (à partir d'une exécution différente, peut ne pas correspondre exactement à l'exemple ci-dessus)

warn
error

Ensuite, j'ai pensé que je devrais le changer pour qu'il corresponde davantage :

errorRegEx := regexp.MustCompile(`(?is).*error.*|.*warn.*`)

Mais cela n’imprime rien du tout

Comment obtenir la ligne complète et toutes les lignes où l'avertissement ou l'erreur (insensible à la casse) correspondront ?

ps : Ce n'est pas la même chose que la ligne de correspondance d'expression régulière suggérée contenant une chaîne, car il s'agit d'une question spécifiquement pour le langage go, qui ne semble pas utiliser exactement le même moteur standard.

Solution de contournement

Considérant que la question a été marquée comme dupe, le commentaire de l'op est le suivant.

Cette question est marquée comme un doublon, et le message lié contient de nombreuses réponses que nous pouvons utiliser pour essayer de rassembler une réponse à la question du PO, mais il n'est toujours pas complet car les réponses semblent être liées à pcre and go en utilisant 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)
}

Tout d'abord, je ne comprends pas pourquoi cela n'imprime rien pour l'opération :

Ensuite, j'ai pensé que je devrais le changer pour qu'il corresponde davantage :

errorregex := regexp.mustcompile(`(?is).*error.*|.*warn.*`)

Mais cela n’imprime rien du tout

Parce que tout doit être imprimé  :

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,并且因为您的星星 (*) est gourmand^2, si une "erreur" ou un "avertissement" est trouvé, ils correspondront à tout dans la chaîne entière.

La vraie solution est de ne pas faire correspondre les points - supprimez le drapeau s et vous obtenez le résultat souhaité :

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"

Maintenant, nous faisons la correspondance entre "n" instances (lignes valides) car nous utilisons le formulaire all, qui recherche uniquement les correspondances qui ne se chevauchent pas :

Si « tout » est présent, la routine fera correspondre les correspondances consécutives sans chevauchement de l'expression entière.

^3

Nous obtenons des lignes complètes et claires.

Vous pouvez resserrer légèrement cette expression régulière :

`(?i).*(?:error|warn).*` // "anything before either "error" or "warn" and anything after (for a line)"

est un (?:...)groupe qui ne capture pas ^1 parce que vous ne semblez pas vous soucier des cas individuels d'"erreur" ou d'"avertissement" dans chaque match.

De plus, je veux toujours montrer que le fractionnement par ligne avant d'essayer de faire correspondre vous donne plus de contrôle/précision et rend les expressions régulières très faciles à raisonner :

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"

Les trois exemples sont situés dans

ce terrain de jeu.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer