Beschreibung | Diese Funktionen sind allgemeine Funktionen zur Behandlung von regulären Ausdrücken in Programmen, die Mustervergleiche von regulären Ausdrücken durchführen. Diese Funktionen werden in der Include-Datei regexp.h definiert. In einem Programm müssen vor der Anweisung #include <regexp.h> die folgenden Makros vom Benutzer definiert werden . Diese Makros werden von der Funktion compile() benutzt. Die Makros GETC() , PEEKC() und UNGETC() arbeiten mit dem regulären Ausdruck, der als Eingabe an compile() übergeben wurde. GETC()
| liefert den Wert des nächsten Zeichens im regulären Ausdruck. Der Benutzer muss darauf achten, dass wiederholte, aufeinander folgende Aufrufe von GETC() aufeinander folgende Zeichen des regulären Ausdrucks ausgeben. | PEEKC()
| liefert das nächste Zeichen im regulären Ausdruck. Der Benutzer muss darauf achten, dass wiederholte, unmittelbar aufeinander folgende Aufrufe von PEEKC() immer dasselbe Zeichen liefern, das zudem mit dem nächsten, von GETC() gelieferten Zeichen identisch sein sollte. | UNGETC( c )
| bewirkt, dass beim nächsten Aufruf von GETC() und PEEKC() das Argument c ausgegeben wird. Es ist nur ein Zeichen notwendig, das in die Eingabe zurückgeschoben wird, und dieses Zeichen ist in jedem Fall das letzte von GETC() eingelesene Zeichen. Der Wert des Makros UNGETC( c ) wird immer ignoriert. | RETURN( ptr ) | wird bei einer normalen Beendigung der Funktion compile() benutzt. Der Wert des Arguments ptr ist ein Zeiger auf das Zeichen, das auf das letzte Zeichen des übersetzten regulären Ausdrucks folgt. Dieses Makro ist bei Programmen hilfreich, die Speicherbereiche verwalten. | ERROR( val )
| entspricht der abnormalen Beendigung der Funktion compile() . Das Argument val ist eine Fehlernummer (Bedeutung der einzelnen Returnwerte siehe unter Fehler). Der Benutzer muss darauf achten, dass dieser Aufruf nicht zurückkehrt. Die Funktionen step() und advance() führen Mustervergleiche durch, bei denen eine Zeichenkette und ein übersetzter regulärer Ausdruck als Eingabe verwendet werden. | compile() nimmt als Eingabe einen regulären Ausdruck und erzeugt einen übersetzten Ausdruck, der mit step() oder advance() verwendet werden kann.
Die Syntax der Funktion compile() ist die folgende: char *compile(char * instring
, char * expbuf
, const char * endbuf
, int eof );
Der erste Parameter instring wird niemals direkt von der Funktion compile() benutzt, ist aber nützlich für Programme, die verschiedene Zeiger auf Eingabezeichen übergeben. Er wird manchmal in den Deklarationen zu INIT verwendet (siehe auch unten). Programme, die Funktionen aufrufen, um Zeichen einzugeben, oder die Zeichen aus einem externen Vektor verarbeiten, können hier den Wert (char*)0 übergeben. Der nächste Parameter expbuf ist ein Zeiger auf char . Er zeigt auf die Stelle, an der der übersetzte reguläre Ausdruck abgelegt werden soll. Der Parameter endbuf ist um eins höher als die höchste Adresse, in die der übersetzte reguläre Ausdruck eingetragen werden soll. Wenn der übersetzte Ausdruck nicht in (endbuf-expbuf)-Bytes passt, dann wird ERROR(50) aufgerufen. Der Parameter eof ist das Zeichen, das das Ende eines regulären Ausdruckes kennzeichnet.
Jedes Programm, das die #include- Anweisung für regexp.h enthält, muss auch eine #define- Anweisung für das Makro INIT enthalten. Dieses Makro wird für abhängige Vereinbarungen und Initialisierungen verwendet. In den meisten Fällen wird es dazu verwendet, eine Registervariable so zu setzen, dass sie auf den Anfang des regulären Ausdrucks zeigt, so dass diese Registervariable in den Vereinbarungen von GETC() , PEEKC() undUNGETC() verwendet werden kann. Ansonsten kann es benutzt werden, um externe Variablen zu vereinbaren, die von GETC() , PEEKC() und UNGETC() benutzt werden könnten. Die Funktionen step() und advance() haben jeweils zwei Parameter: string, der erste Parameter, ist ein Zeiger auf eine Zeichenkette, die gegen einen regulären Ausdruck geprüft werden soll. Diese Zeichenkette muss mit dem Nullbyte abgeschlossen sein. expbuf, der zweite Parameter, ist der übersetzte reguläre Ausdruck, der von einem Aufruf der Funktion compile() geliefert wurde.
Die Funktion step() liefert einen Wert ungleich null, wenn eine Teilfolge von string zu dem regulären Ausdruck expbuf passt; sie liefert den Wert Null, wenn es keine Übereinstimmung gibt. Wenn eine Übereinstimmung vorliegt, werden zwei externe Zeiger als Seiteneffekt des Aufrufs von step() gesetzt. Die Variable loc1 zeigt dann auf das erste, zum regulären Ausdruck passende Zeichen; die Variable loc2 zeigt auf das Zeichen nach dem letzten Zeichen, das zum regulären Ausdruck passt. Wenn also die gesamte Eingabezeichenkette zum regulären Ausdruck passt, so zeigt loc1 auf das erste Zeichen von string, und loc2 zeigt auf das Nullbyte am Ende von string. advance() liefert einen Wert ungleich null, wenn die erste Teilfolge von string zum regulären Ausdruck in expbuf passt. Gibt es eine Übereinstimmung, dann wird als Seiteneffekt ein externer Zeiger loc2 auf char gesetzt. Die Variable loc2 zeigt auf das nächste Zeichen in string, das sich hinter dem letzten passenden Zeichen befindet.
Trifft die Funktion advance() auf ein Zeichen * oder auf die Zeichenkette \{\} im regulären Ausdruck, so setzt sie ihren Zeiger hinter die größtmögliche dazu passende Zeichenkette und ruft sich selbst rekursiv auf, um den Rest der Zeichenkette mit dem Rest des regulären Ausdrucks zu vergleichen. Solange keine Übereinstimmung vorliegt, wird geprüft, ob das gesuchte Muster bereits im vorher erkannten Teilstring enthalten ist. Dabei wird jeweils um eine Stelle zurückgerückt, bis eine Übereinstimmung festgestellt wird oder bis die Stelle in der Zeichenkette erreicht ist, die anfangs zu dem * oder der Zeichenkette \{\} passte. In manchen Fällen ist es wünschenswert, dass das Zurückgehen abgebrochen wird, bevor diese Stelle erreicht ist. Ist der externe Zeiger locs zu irgendeinem Zeitpunkt während des Zurückgehens identisch mit dieser Stelle in der Zeichenkette, so beendet aadvance() die Schleife und gibt den Wert Null zurück. Die externen Variablen circf, sed und nbra sind reserviert. Einfache reguläre Ausdrücke (historische Version)Ein einfacher regulärer Ausdruck vereinbart eine Menge von Zeichenketten. Wenn eine Zeichenkette in dieser Menge liegt, wird gesagt, dass es auf den einfachen regulären Ausdruck passt. Ein Muster wird von einem einfachen regulären Ausdruck oder von mehreren einfachen regulären Ausdrücken gebildet. Ein einfacher regulärer Ausdruck besteht aus normalen Zeichen oder aus Metazeichen. Syntaxelemente zur Bildung von Mustern: regulärer Ausdruck | Bedeutung | Beispiel | passende Zeichenkette | r+ | Einmal oder mehrmals der reguläre Ausdruck r. r muss von einer der folgenden Formen sein: r, \ r, beliebiges Zeichen, [ r ] , [ r1-r2 ] , [^ s ] ,[^ r1-r2 ] , ( r ) , ( r1 | r2 ) | u+
| u , uu , uuu , ... | r? | Null- oder einmal der reguläre Ausdruck r. r muss von einer der folgenden Formen sein: r, \ r, beliebiges Zeichen, [ r ] , [ r1-r2 ] , [^ s ] , [^ r1-r2 ] , ( r ) , ( r1 | r2 ) | u?
| nichts oder u | ( r ) | Zeichenketten, die zu dem regelären Ausdruck r passen. r kann ein beliebiger Ausdruck sein. | (ok(abc)) (au)* | okabc nichts oder au , auau , ...
| ( r1 | r2 ) | Zeichenketten, die zu dem regulären Ausdruck r1 oder zu dem regulären Ausdruck r2 passen. | (ok|ko)
| ok oder ko
| Innerhalb eines Musters passen alle alphanumerischen Zeichen, die nicht Teil eines Klammerausdrucks, Rückbezugs oder eines Duplikats sind, auf sich selber. Das bedeutet, das Muster abc des regulären Ausdrucks passt, wenn es auf eine Menge von Zeichenketten angewendet wird, auf die Zeichenketten verglichen, die auch die Zeichenfolge abc enthalten. Nur einige Zeichen, die Metazeichen, haben eine besondere Bedeutung, wenn sie in einem regulären Ausdruck verwendet werden; andere Zeichen stehen für sich selbst. Die regulären Ausdrücke, die mit den regexp -Funktionen verfügbar sind, werden folgendermaßen erzeugt: Ausdruck | Bedeutung | c | Das Zeichen c, wobei c kein Sonderzeichen sein darf. | \ c
| Das Zeichen c, wobei c kein Sonderzeichen sein darf. Das Zeichen c, wobei c irgendein Zeichen ist, außer einer Ziffer im Bereich 1-9. | ^
| Der Anfang der Zeile, auf der der Vergleich durchgeführt wird. | $
| Das Ende der Zeile, auf der der Vergleich durchgeführt wird. | .
| Irgendein Zeichen in der Eingabe. | [s] | Irgendein Zeichen in der Menge s, wobei s eine Folge von Zeichen ist. Bereiche können als[ c-c ] angegeben werden. In dieser Menge kann das Zeichen ] nur an erster Stelle stehen, das Zeichen - kann an erster oder letzter Stelle stehen, das Zeichen ^ kann an jeder Stelle stehen, nur nicht an der ersten. Bereiche in einfachen regulären Ausdrücken sind nur gültig, wenn die Kategorie LC_COLLATE auf die C-Lokalität gesetzt wird. | [^ s] | Irgendein Zeichen, das nicht in der Menge s liegt, wobei s wie oben definiert ist. | r* | Null oder mehrere aufeinander folgende Vorkommen des regulären Ausdrucks r. Die längste, am weitesten links liegende, passende Zeichenkette wird verwendet. | rx | Das Vorkommen des regulären Ausdrucks r, gefolgt vom Vorkommen des regulären Ausdrucks x (Verkettung). | r \{ m , n \} | Irgendeine Anzahl zwischen m und n aufeinander folgender Vorkommen des regulären Ausdrucks r. Der reguläre Ausdruck r \{ m \} passt bei genau m Vorkommen; r \{ m,\} passt bei mindestens m Vorkommen. Die maximale Anzahl der Vorkommen wird geprüft. | \( r \)
| Der reguläre Ausdruck r. Die Folgen \ ( und \ ) werden ignoriert. | \n | Wenn \ n eine Ziffer im Bereich von 1-9 ist und in einem verketteten regulären Ausdruck vorkommt, steht es für den regulären Ausdruck x. Dabei ist x der n-te reguläre Ausdruck, eingeschlossen in \( und \) , der in dem vorher geketteten regulären Ausdruck vorkam. In dem Muster \( r \) x \( y ) z \2 vergleicht \2 den regulären Ausdruck y und ergibt rxyzy. | Folgende Zeichen haben eine besondere Bedeutung, wenn sie nicht innerhalb von eckigen Klammern [ ] auftreten oder ihnen ein \ vorangeht: . , *, [ , \ . Andere Sonderzeichen, wie z.B. $ haben in noch weiter eingeschränkten Umgebungen eine besondere Bedeutung. Steht das Zeichen ^ am Anfang eines Ausdrucks, können nur Zeichenfolgen passen, die unmittelbar nach einem Zeilenendezeichen stehen oder am Anfang einer jeden Zeichenkette, bei der der Vergleich angewendet wird. Das Zeichen $ am Ende eines Ausdrucks verlangt ein abschließendes Zeilenendezeichen. Zwei Zeichen haben nur dann eine besondere Bedeutung, wenn sie innerhalb von eckigen Klammern verwendet werden. Das Zeichen - gibt einen Bereich an, [ c-c ] , außer wenn es direkt nach einer öffnenden oder direkt vor einer schließenden Klammer auftritt, [- c ] oder [ c -] . In diesem Fall hat es keine besondere Bedeutung. Bei der Verwendung innerhalb von eckigen Klammern hat das Zeichen ^ die Bedeutung „Komplement von“, wenn es unmittelbar auf die öffnende eckige Klammer folgt ( [^ c ] ); sonst steht es zwischen eckigen Klammern ( [ c ^] ) für das normale Zeichen ^ . Die schließende eckige Klammer hat keine besondere Bedeutung mehr, wenn sie direkt dem ersten Zeichen ^ folgt. Sie steht dann als normale schließende Klammer in einem Klammerausdruck. Die besondere Bedeutung des Operators \ kann nur durch das Voran Stellen eines weiteren \ , d.h \\ , ausgeschaltet werden. Rangfolge der Operatoren für einfache reguläre Ausdrücke [...] | hohe Rangfolge | Verkettung | niedrige Rangfolge | Internationalisierte einfache reguläre AusdrückeZeichenausdrücke in eckigen Klammern werden wie folgt gebildet: c | ein einzelnes Zeichen c, wobei c kein Sonderzeichen ist. | [[:class:]] | Ein char -Klassenausdruck. Jedes Zeichen vom Typ class , wie durch die Kategorie LC_CTYPE in der Programmlokalität definiert (siehe Handbuch „POSIX-Kommandos“ [ 2 ]). | Anstelle von class kann Folgendes angegeben werden: alpha | ein Buchstabe | upper | ein Großbuchstabe | lower | ein Kleinbuchstabe | digit | eine Ziffer | xdigit | eine hexadezimale Ziffer | alnum | ein alphanumerisches Zeichen (Buchstabe oder Ziffer) | space | ein Leerzeichen | punct | ein Interpunktionszeichen | print | ein abdruckbares Zeichen | graph | ein sichtbares Zeichen | cntrl | ein Steuerzeichen | [[=c=]] | Eine Äquivalenzklasse. Jede Zeicheneinheit, die so definiert ist, als hätte sie dieselbe relative Reihenfolge in der aktuellen Sortierreihenfolge wie c. Beispiel: wenn A und a derselben Äquivalenzklasse angehören, dann entsprechen [[ =A= ] b ] und [[ =a= ] b ] beide [ Aab ] . | [[.cc.]] | Ein Zeicheneinheits-Symbol. Mehrzeichen-Zeicheneinheiten müssen als Zeicheneinheits-Symbole dargestellt werden, um sie von Einzelzeichen-Zeicheneinheiten unterscheiden zu können. Wenn zum Beispiel ch eine gültige Zeicheneinheit ist, dann wird die Zeichenkette [[ .ch. ]] als ein Element betrachtet, das genau auf dieselbe Zeichenkette passt, während ch als einfaches c und h betrachtet wird. Ist ch keine gültige Zeicheneinheit in der aktuellen Definition der Sortierreihenfolge, wird das Symbol als ungültiger Ausdruck behandelt. | [c-c] | Jede Vergleichseinheit im Bereich des Zeichenausdrucks c-c, wobei c ein Zeicheneinheits-Symbol oder eine Äquivalenzklasse sein kann. Befindet sich das Zeichen - unmittelbar nach einer öffnenden eckigen Klammer, zum Beispiel [ -c ] oder vor einer schließenden, zum Beispiel [ c- ] , so hat dies keine besondere Bedeutung. | ^
| Folgt das Zeichen c unmittelbar einer öffnenden eckigen Klammer, so ist es das Komplement von zum Beispiel [^ c ] . Ansonsten hat dies keine besondere Bedeutung. | Bei innerhalb von eckigen Klammern stehenden Ausdrücken ist a . nicht Teil der Folge a [[ .cc. ]] oder a : nicht Teil der Folge a [[ :class:]] oder an = nicht Teil der Folge a [[ =c= ]] . Diese Folgen stimmen nur mit Zeichenketten überein, die dieselben Folgen haben. Beispiele für reguläre Ausdrücke ab.d
| ab beliebiges Zeichen d | ab.*d
| ab jede Folge des Zeichens (inkl. kein Zeichen) d | ab[xyz]d | ab eines der Zeichen x y oder z d | ab[^c]d
| ab jedes Zeichen, ausgenommen c d | ^abcd$
| eine Zeile, die nur abcd enthält | a-d
| jedes der Zeichen a b c oder d | |