Reguläre Ausdrücke in Check_MK

Letzte Aktualisierung: 08. Februar 2018


1. Einleitung

Reguläre Ausdrücke – kurz Regexe –, werden in Check_MK für die Angabe von Service­namen und auch an vielen anderen Stellen verwendet. Es sind Muster, die auf einen bestimmten Text passen (matchen) oder nicht passen. Damit können Sie viele praktische Dinge anstellen, wie z. B. flexible Regeln formulieren, die für alle Services greifen, bei denen foo oder bar im Namen vorkommt.

Oft werden Regexe mit den Suchmustern für Dateinamen verwechselt, denn die Sonderzeichen * und ? gibt es in beiden. Nur haben jene sogenannten Globbing patterns eine ganz andere Syntax und sind bei weitem nicht so mächtig wie die regulären Ausdrücke. Wenn Sie unsicher sind, ob an einer Stelle reguläre Ausdrücke erlaubt sind, dann schalten Sie am besten die Onlinehilfe an.

In diesem Artikel zeigen wir Ihnen die wichtigsten Möglichkeiten der regulären Ausdrücke – aber bei weitem nicht alle. Wenn Ihnen die hier gezeigten Möglichkeiten nicht weit genug gehen, finden Sie weiter unten Hinweise, wo Sie alle Details nachlesen können. Und dann gibt es ja immer noch das Internet.

1.1. Normale Zeichen und der Punkt

Bei den regulären Ausdrücken geht es immer darum, ob ein Muster (der Ausdruck) auf einen bestimmten Text (z. B. einen Servicenamen) passt (matcht). Dabei darf das Muster eine Reihe von Sonderzeichen enthalten, welche dann „magische“ Bedeutungen haben. Alle normalen Zeichen im Ausdruck matchen einfach sich selbst.

Check_MK unterscheidet dabei nicht zwischen Groß- und Kleinschreibung. Der Ausdruck CPU load matcht also auf den Text CPU load genauso wie auf cpu LoAd. Achtung: Bei Eingabefeldern, wo ohne reguläre Ausdrücke ein exakter Match vorgesehen ist (meistens bei Hostnamen), wird Groß und Klein immer unterschieden!

Das wichtigste Sonderzeichen ist der . Punkt. Er matcht ein beliebiges Zeichen:

Beispiel:

Regular Expression Match Match Kein Match
Me.er Meier Meyer Meyyer
.var.log 1var2log /var/log /var//log

1.2. Sonderzeichen mit Backslash maskieren

Da der Punkt alles matcht, matcht er natürlich auch einen Punkt. Wenn Sie nun aber genau einen Punkt matchen wollen, so müssen Sie diesen mit einem \ Backslash maskieren (eingedeutscht: „escapen“). Das gilt analog auch für alle anderen Sonderzeichen, die Sie noch kennenlernen werden. Dies sind: \ . * + ? { } ( ) [ ] | & ^ und $. Der \ Backslash wertet das nächste Sonderzeichen als normales Zeichen:

Regular Expression Match Kein Match Kein Match
example\.com example.com example\.com example-com
Wie\? Wie? Wie\? Wie
C:\\Programs C:\Programs C:Programs C:\\Programs

1.3. Wiederholungen von Zeichen

Sehr oft möchte man definieren, dass irgendwo im Ausdruck eine beliebige Folge von Zeichen vorkommen darf. In Regexen schreiben Sie das mit .* (Punkt Stern). Eigentlich ist das aber nur ein Spezialfall. Denn Sie können den Stern einem beliebigen Zeichen nachstellen, welches dann im Suchtext beliebig oft hintereinander vorkommen darf. Dabei gilt auch eine leere Folge als Folge. Das heißt, .* matcht eine beliebige Zeichenfolge und * matcht das vorherige Zeichen beliebig oft:

Regular Expression Match Match Kein Match
State.*OK State is OK State = OK StatOK
State*OK StateOK StatOK State OK
a *= *5 a=5 a = 5 a==5

Das + ist fast das Gleiche wie *, erlaubt aber keine leere Folge. Das vorangestellte Zeichen muss also mindestens einmal vorkommen:

Regular Expression Match Match Kein Match
State +OK State OK State  OK StateOK
switch +off switch off switch  off switchoff

Möchten Sie die Anzahl von Wiederholungen genauer festlegen, so gibt es dafür eine Syntax mit ge­schweif­ten Klammern, die die exakte Anzahl oder einen Bereich angibt:

Regular Expression Match Match Kein Match
Ax{3}B AxxxB AxB
Ax{2,4} Axx Axxxx Ax

Eine Abkürzung für {0,1}, also ein- oder keinmaliges Vorkommen, ist das Fragezeichen. Es markiert das vorangegangene Zeichen somit als optional:

Regular Expression Match Match Kein Match
a-?b ab a-b a--b
Meyi?er Meyer Meyier Meyiier

1.4. Zeichenklassen, Ziffern und Buchstaben

Zeichenklassen erlauben Dinge wie „hier muss eine Ziffer kommen“. Dazu setzen Sie in eckige Klammern alle erlaubten Zeichen. Mit einem Minuszeichen können Sie auch Bereiche angeben. Achtung: Es gilt dabei die Reihenfolge im ASCII-Zeichensatz.

So steht beispielsweise [abc] für genau eines der Zeichen a, b oder c und [0-9] für eine beliebige Ziffer - beides lässt sich kombinieren. Auch eine Negation des Ganzen ist möglich: Mit einem ^ in der Klammer steht [^abc] dann für ein beliebiges Zeichen außer a, b, c.

Zeichnklassen lassen sich natürlich mit anderen Operatoren kombinieren. Zunächst mal einige abstrakte Beispiele:

Zeichenklasse Bedeutung
[abc] Genau eines der Zeichen a, b, c.
[0-9a-z_] Genau eine Ziffer, ein Buchstabe oder ein Unterstrich.
[^abc] Beliebiges Zeichen außer a, b, c.
[ --] Genau ein Zeichen zwischen Leerzeichen und Minus gemäß ASCII-Tabelle.
[0-9a-z]{1,20} Bezeichner mit maximal 20 Buchstaben oder Ziffern.

Dazu einige praktische Beispiele:

Regular Expression Match Match Kein Match
[0-7] 0 5 9
[0-7]{2} 00 53 123
myhost_[0-9a-z_]{3} myhost_1a3 myhost_1_5 myhost_1234
[+0-9/ --]+ +49 89 998209700 089 / 9982 097-00 089 : 9982 097-00

Achtung: Wenn Sie eines der beiden Zeichen - oder ] brauchen, müssen Sie etwas tricksen. Den - schrei­ben Sie einfach direkt ans Ende der Klasse – wie in obigen Beispielen bereits gezeigt. Dann ist dem Regexauswerter klar, dass es keine Folge sein kann. Und die eckige Klammer platzieren Sie als erstes Zeichen in der Klasse. Da keine leeren Klassen erlaubt sind, wird das dann als normales Zeichen gewertet. Eine Klasse mit genau diesen beiden Sonderzeichen sähe also so aus: []-].

1.5. Anfang und Ende, Präfix, Suffix und Infix

Check_MK prüft beim Vergleichen von regulären Ausdrücken mit Servicenamen und anderen Dingen grundsätzlich, ob der Text mit dem Anfang des Ausdrucks übereinstimmt. Der Grund dafür ist, dass das meistens das ist, was Sie brauchen. Eine Regel, in der Sie bei Services die Begriffe CPU und Kernel angeben, matcht also auf alle Services, die mit einem dieser Begriffe beginnen:

Das bezeichnet man auch als Präfixmatch. Benötigen Sie einen exakten Match, so können Sie das durch Anhängen eines $ bewerkstelligen. Dieser matcht quasi auf das Ende des Texts. Genügt es, wenn der Ausdruck irgendwo im Text matcht, ein so genannter Infixmatch, erreichen Sie das mit dem bekannten .* vorab:

Regular Expression Match Match Kein Match
/var /var /var/log /test/var
/var$ /var /var/log
.*/var$ /var /test/var /var/log
.*/var /test/var /test/var/log \test\var\log

Eine Ausnahme von der Regel, dass Check_MK immer einen Präfixmatch verwendet, ist die Event Console (EC), welche immer mit einem Infixmatch arbeitet – also nur auf Enthaltensein prüft. Hier können Sie durch Voranstellen von ^ ein Match für den Anfang erzwingen, also einen Präfixmatch.

Regular Expression in EC Match Match Kein Match
ORA- ORACLEserver myORACLEserver myoracleserver
^ORA- ORACLEserver ORACLEhost myORACLEserver

1.6. Alternativen

Mit dem | senkrechten Balken können Sie Alternativen definieren, sprich eine ODER-Verküpfung verwenden: 1|2|3 matcht also auf 1, 2 oder 3. Wenn Sie die Alternativen inmitten eines Ausdrucks benötigen, setzen Sie diese in runde Klammern.

Regular Expression Match Match Kein Match
CPU load|Kernel|Memory CPU load Kernel CPU utilization
01|02|1[1-5] 01 11 bis 15 05
server\.(intern|dmz|123)\.net server.intern.net server.dmz.net server.extern.net

1.7. Matchgruppen

In der Event Console, im Business Intelligence (BI) und auch beim Massenumbenennen von Hosts besteht die Möglichkeit, dass Sie sich auf Textteile beziehen, die im Ursprungstext gefunden wurden. Dabei werden Muster in regulären Ausdrücken mit Klammern markiert. Der Textteil, der auf den ersten Klammerausdruck passt, steht dann beim Ersetzen als \1 zur Verfügung, der zweite Ausdruck als \2 usw.

Regular Expression Text Gruppe 1 Gruppe 2
([a-z])+([123])+ abc123 abc 123
server-(.*)\.local server-lnx02.local lnx02

Folgende Abbildung zeigt eine solche Umbenennung. Alle Hostnamen, die auf den regulären Ausdruck server-(.*)\.local passen, werden durch \1.servers.local ersetzt. Dabei steht das \1 genau für den Text, der mit dem .* in der Klammer „eingefangen“ wurde:

Im konkreten Fall wird also server-lnx02.local in lnx02.servers.local umbenannt.

Sie können Gruppen natürlich auch mit den Operatoren für Wiederholungen, *, +, ? und {...} kombinieren. So passt etwa der Ausdruck (/local)?/share sowohl auf /local/share als auch auf /share.

2. Tabelle aller Sonderzeichen

Hier noch einmal zusammengefasst die Liste von allen oben erklärten Sonderzeichen und Funktionen der regulären Ausdrücke, die Check_MK verwendet:

. Passt auf ein beliebiges Zeichen
\ Wertet das nächste Sonderzeichen als normales Zeichen
* Das vorherige Zeichen darf beliebig oft kommen (auch 0-mal)
+ Das vorherige Zeichen muss mindestens einmal vorkommen.
{5} Das vorherige Zeichen muss genau fünfmal vorkommen.
{5,10} Das vorherige Zeichen muss zwischen fünf und zehnmal vorkommen.
? Das vorherige Zeichen darf 0 oder einmal vorkommen.
[abc] Steht für genau eines der Zeichen a, b oder c.
[0-9] Steht für genau eines der Zeichen 0, 1 ... 9 (also eine Ziffer).
[0-9a-z_] Steht für genau eine Ziffer, einen Buchstaben oder den Unterstrich.
[^"'] Steht für genau ein beliebes Zeichen außer dem einfachen oder Anführungszeichen.
$ Match auf das Ende eines Textes.
^ Match auf den Anfang eines Textes.
A|B|C Matcht auf A oder auf B oder auf C.
(A) Fasst den Unterausdruck A zu einer Gruppe zusammen.

Folgende Zeichen müssen durch Backslash maskiert/escaped werden, wenn sie wörtlich verwendet werden sollen: \ . * + ? { } ( ) [ ] | & ^ $

3. Wenn Sie es genau wissen möchten

Ken Thompson, einer der Erfinder von UNIX, hat schon in den 1960ern als erster reguläre Ausdrücke in der heutigen Form entwickelt – unter anderem im bis heute gebräuchlichen Unix-Befehl grep. Seitdem wurden zahlreiche Erweiterungen und Dialekte von regulären Ausdrücken geschaffen – darunter erweiterter Regexe, Perl-kompatible Regexe und auch eine sehr ähnlich Variante in Python.

Check_MK verwendet in den Filtern in Views POSIX erweiterte reguläre Ausdrücke (extended REs). Diese werden im Monito­ring­kern in C mit der Regexfunktion der C-Bibliothek ausgewertet. Sie finden eine kom­plette Refe­renz dazu in der Linux-Manpage zu regex(7):

OMD[mysite]:~$ man 7 regex

REGEX(7)                   Linux Programmer's Manual                   REGEX(7)

NAME
       regex - POSIX.2 regular expressions

DESCRIPTION
       Regular  expressions  ("RE"s), as defined in POSIX.2, come in two forms:
       modern REs (roughly those of egrep; POSIX.2 calls these "extended"  REs)
       and  obsolete  REs (roughly those of ed(1); POSIX.2 "basic" REs).  Obso-
       lete REs mostly exist for backward compatibility in some  old  programs;

An allen anderen Stellen stehen darüber hinaus alle Möglichkeiten der regulären Ausdrücke von Python zur Verfügung. Dies betrifft unter anderem die Konfigurationsregeln, die Event Console und das Business Intelli­gence (BI). Die Python-Regexe sind eine Erweiterung der extended REs und sehr ähnlich zu denen aus Perl. Sie unterstützen z. B. den sogenannten negative Lookahead, einen nicht gierigen * Stern, oder ein Erzwingen der Unterscheidung von Groß-/Kleinschreibung. Die genauen Möglichkeiten dieser Regexe finden Sie in der Online-Hilfe von Python zum Modul re:

OMD[mysite]:~$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> help(re)
Help on module re:

NAME
    re - Support for regular expressions (RE).

FILE
    /usr/lib/python2.7/re.py

MODULE DOCS
    http://docs.python.org/library/re

DESCRIPTION
    This module provides regular expression matching operations similar to
    those found in Perl.  It supports both 8-bit and Unicode strings; both
    the pattern and the strings being processed can contain null bytes and
    characters outside the US ASCII range.

    Regular expressions can contain both special and ordinary characters.
    Most ordinary characters, like "A", "a", or "0", are the simplest
    regular expressions; they simply match themselves.  You can
    concatenate ordinary characters, so last matches the string 'last'.

    The special characters are:
        "."      Matches any character except a newline.
        "^"      Matches the start of the string.
        "$"      Matches the end of the string or just before the newline at
                 the end of the string.
        "*"      Matches 0 or more (greedy) repetitions of the preceding RE.
                 Greedy means that it will match as many repetitions as possible.
        "+"      Matches 1 or more (greedy) repetitions of the preceding RE.
        "?"      Matches 0 or 1 (greedy) of the preceding RE.
        *?,+?,?? Non-greedy versions of the previous three special characters.
        {m,n}    Matches from m to n repetitions of the preceding RE.
        {m,n}?   Non-greedy version of the above.
        "\\"     Either escapes special characters or signals a special sequence.
        []       Indicates a set of characters.
                 A "^" as the first character indicates a complementing set.
        "|"      A|B, creates an RE that will match either A or B.
        (...)    Matches the RE inside the parentheses.
                 The contents can be retrieved or matched later in the string.
        (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below).
        (?:...)  Non-grouping version of regular parentheses.
        (?P<name>...) The substring matched by the group is accessible by name.
        (?P=name)     Matches the text matched earlier by the group named name.
        (?#...)  A comment; ignored.
        (?=...)  Matches if ... matches next, but doesn't consume the string.
        (?!...)  Matches if ... doesn't match next.
        (?<=...) Matches if preceded by ... (must be fixed length).
        (?<!...) Matches if not preceded by ... (must be fixed length).
        (?(id/name)yes|no) Matches yes pattern if the group with id/name matched,
                           the (optional) no pattern otherwise.

    The special sequences consist of "\\" and a character from the list
    below.  If the ordinary character is not on the list, then the
    resulting RE will match the second character.
        \number  Matches the contents of the group of the same number.
        \A       Matches only at the start of the string.
        \Z       Matches only at the end of the string.
        \b       Matches the empty string, but only at the start or end of a word.
        \B       Matches the empty string, but not at the start or end of a word.
        \d       Matches any decimal digit; equivalent to the set [0-9].
        \D       Matches any non-digit character; equivalent to the set [^0-9].
        \s       Matches any whitespace character; equivalent to [ \t\n\r\f\v].
        \S       Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v].
        \w       Matches any alphanumeric character; equivalent to [a-zA-Z0-9_].
                 With LOCALE, it will match the set [0-9_] plus characters defined
                 as letters for the current locale.
        \W       Matches the complement of \w.
        \\       Matches a literal backslash.

Copyright © 2001-2018 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
Copyright © 1995-2000 Corporation for National Research Initiatives. All rights reserved.
Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved.

License: https://docs.python.org/2/license.html

Eine sehr ausführliche Erklärung zu regulären Ausdrücken finden Sie in der Wikipedia.