Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Code Generierungstechniken • • • • • • Andreas Schmidt Code Munger Inline code expander Mixed code generation Partial class generation Full Tier or layer generation Domain specific language Übersicht Codegeneratoren 1/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Code Munging • Funktionsweise: • Input ist Quellcode • Analysieren der Eingabedatei und Generierung von Output • Einsatzbereiche: • Programmdokumentation (Extraktion von Kommentaren) • Erstellung eines Index für Klassen/Methoden • Quellcode analysieren • Filter • Anwendungsbeispiele: • JavaDoc • XDoclet (Java Annotation) Andreas Schmidt Quellcode Code Munger Ausgabedatei Übersicht Codegeneratoren 2/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • weitere Beispiele • Generierung eines Klassen-/Methodenindex in HTML • Generierung von Basisklassen • Generierung von SQL-Statements aus CSV-Datei • Generierung von Basisklassen aus DDL-Statements • Quellcode Analyse • Modifikation von XML-Dokumenten (ohne XSLT/DOM) • ... Andreas Schmidt Übersicht Codegeneratoren 3/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel 1 • Welche Klassen und Methoden gibt es in PEAR/MDB2.php? $ grep -E '^\s*(function|class)' d:/Programme/xampp/php/PEAR/MDB2.php class MDB2 function setOptions(&$db, $options) function classExists($classname) function loadClass($class_name, $debug) function &factory($dsn, $options = false) function &connect($dsn, $options = false) function &singleton($dsn = null, $options = false) function loadFile($file) function apiVersion() function &raiseError($code = null, $mode = null, $options = null, $userinfo = null) function isError($data, $code = null) function isConnection($value) ... class MDB2_Error extends PEAR_Error function MDB2_Error($code = MDB2_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null) class MDB2_Driver_Common extends PEAR function __construct() Andreas Schmidt Übersicht Codegeneratoren 4/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Ausgabeformatierung in HTML $ grep -E '^\s*(function|class)' d:/Programme/xampp/php/PEAR/MDB2.php | sed -r 's#(class \w+.*)\s+\w+#<h1>\1</h1>#;s#function &?(\w+)(.*)# \ <p><b>\&nbsp;\&nbsp;method \1</b>\2#' <h1>class MDB2</h1> <p><b>&nbsp;&nbsp;method setOptions</b>(&$db, $options) <p><b>&nbsp;&nbsp;method classExists</b>($classname) <p><b>&nbsp;&nbsp;method loadClass</b>($class_name, $debug) <p><b>&nbsp;&nbsp;method factory</b>($dsn, $options = false) <p><b>&nbsp;&nbsp;method connect</b>($dsn, $options = false) <p><b>&nbsp;&nbsp;method singleton</b>($dsn = null, $options = false) <p><b>&nbsp;&nbsp;method loadFile</b>($file) <p><b>&nbsp;&nbsp;method apiVersion</b>() <p><b>&nbsp;&nbsp;method raiseError</b>($code = null, $mode = null, $option = null, $userinfo = null) <p><b>&nbsp;&nbsp;method isError</b>($data, $code = null) <p><b>&nbsp;&nbsp;method isConnection</b>($value) <p><b>&nbsp;&nbsp;method isResult</b>($value) <p><b>&nbsp;&nbsp;method isResultCommon</b>($value) <p><b>&nbsp;&nbsp;method isStatement</b>($value) <p><b>&nbsp;&nbsp;method errorMessage</b>($value = null) <p><b>&nbsp;&nbsp;method parseDSN</b>($dsn) <p><b>&nbsp;&nbsp;method fileExists</b>($file) <h1>class MDB2_Error extends PEAR_Error</h1> <p><b>&nbsp;&nbsp;method MDB2_Error</b>($code = MDB2_ERROR, $mode = PEAR_EROR_RETURN, Andreas Schmidt Übersicht Codegeneratoren 5/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Analyse regulärer Ausdruck • Pattern matching (egrep-syntax) ^\s*(function|class)\s+\w+ one or more alphanumeric characters one or more whitespaces start of line or zero or more whitespaces • Pattern substitution (s # text # relacement #) (extended sed-syntax) store the characters inside ( ) into variable<x> zero or more characters (the rest of the line) optional &-character s#function\s+&?(\w+)(.*)#<p><b>&nbsp;Method \1</b>\2</h4># one or more whitespaces one or more alphanumeric characters Andreas Schmidt Übersicht Codegeneratoren 6/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Output Andreas Schmidt Übersicht Codegeneratoren 7/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Einfache Erweiterung mittels Frameset function isError($value) class MDB2 &nbsp;<b><a href= "DB.html#592 ">function isError($value)</a></b><br/> <h2><a href="DB.html#432 ">class DB</a></h2> MDB2.index.html MDB2.php MDB2.html <pre> ... </pre> around whole document function isError($value) class DB rest Andreas Schmidt </pre><b><a name= "592 ">function isError($value)</a></b><br/><pre> </pre><h2><a name= "432 ">class DB</a></h2><pre> ... Übersicht Codegeneratoren 8/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • MDB2.index.html Andreas Schmidt • MDB2.html Übersicht Codegeneratoren 9/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • Overall effort: • • • • 2 regular expressions for index (one line each) 2 regular expressions for code (one line each) 3 command line calls 1 frameset easily adaptable for many languages !! Andreas Schmidt Übersicht Codegeneratoren 10/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Code Munger - Beispiel (2) File: Person.php <?php <?php class BasePerson { include 'BasePerson.class.php'; protected $name; protected $day_of_birth; class Person extends BasePerson { // @fields: name, day_of_birth function } function return } function return } function return } function return } function age() { $now = time(); $birthday = strtotime($this->day_of_birth); return floor(($now -$birthday)/(3600*24*365)); } } __construct() { get_name() { $this->name; get_day_of_birth() { $this->day_of_birth; set_name($value) { $this->name = $value; set_day_of_birth($value) { $this->day_of_birth = $value; } Andreas Schmidt Übersicht Codegeneratoren 11/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Example (Implementation) File: generate-base-classes.php <?php $lines = file($argv[1]); look for the start of a class definition foreach ($lines as $line) { if (preg_match('#^\s*class\s+\w+\s+extends\s+(\w+)\s*{#', $line, $match)) { $base_class = $match[1]; look for the line with the @fields keyword } else if (preg_match('#^\s*//\s*@fields\s*:\s*(.*)#',$line,$match)) { $attributes = preg_split('#\s*,\s*#', $match[1]); $content = create_base_class($base_class, $attributes); file_put_contents($base_class.".class.php", $content); } } generate class definition write class definition to file Andreas Schmidt Übersicht Codegeneratoren 12/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 function create_base_class($classname, $attributes) { $content = "<?php\n class $classname {\n"; foreach ($attributes as $attribute) { $content .= " protected \$$attribute;\n"; } $content .= "\n function __construct() { }\n"; foreach ($attributes as $attribute) { $content .= "\n function get_$attribute() { return \$this->$attribute; }\n"; } foreach ($attributes as $attribute) { $content .= "\n function set_$attribute(\$value) { return \$this->$attribute = \$value; }\n"; } $content .="\n}"; return $content; } Andreas Schmidt instance variables getter setter Übersicht Codegeneratoren 13/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Run the Test • File: simple_test.php <?php $ php.exe generate-base-classes.php Person.php $ php.exe simple_test.php a little test: Andreas Schmidt is likely 46 years old include 'Person.php'; print "a little test:\n"; $p = new Person(); $p->set_name('Schmidt'); $p->set_first_name('Andreas'); $p->set_day_of_birth('9 September 1965'); print $p->get_first_name()." ". $p->get_name()." is likely ". $p->age()." years old\n"; Andreas Schmidt Übersicht Codegeneratoren 14/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 example: add an attribute to an xml-document Concrete: add attribute stereotype with value entity to element class • Solution 1: use XSLT • Solution 2: use DOM or SAX • Simplest solution: perl regular expression substitution from the command line $ perl -pi.bak -e 's/(<class)(.*?)/\1 stereotpe="entity" \2/' my-model.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE my-model SYSTEM "my-meta.dtd"> <my-model name="DEMO"> <class name="Film"> <attribute name="title" type="String"/> <attribute name="year" type="Integer"/> ... Andreas Schmidt <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE my-model SYSTEM "my-meta.dtd"> <my-model name="DEMO"> <class stereotype="entity" name="Film"> <attribute name="title" type="String"/> <attribute name="year" type="Integer"/> ... Übersicht Codegeneratoren 15/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Inline Code Expansion • Funktionsweise: • Impliziert die Definition einer eigenen (einfachen) Sprache • Vereinfacht Quellcodeerstellung • Generierter Code ist Ausgangspunkt für Compilierung • Einsatzbereiche: • Embedded SQL • Embeded assembler sections • Embedded mathematical equations • Generierung von Basisklassen Quellcode Inline Code Expander Ausgabequellcode Compiler Executable Andreas Schmidt Übersicht Codegeneratoren 16/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel Inline Code Expansion • Source code my-cinema.phpi <?php <class: Person (surname, first_name, day_of_birth) > <class: Film (title, year, director) > Inline Code Expander $p1 = new Person('Waits', 'Tom', '9.9.1949'); $f1 = new Film('Short Cuts', 1989, 'Jim Jarmusch'); echo "a little test:\n--------------\n"; echo $p1->get_surname()." ".$p1->get_first_name()." ". $p1->get_date_of_birth()."\n"; echo $f1->get_title()." ".$f1->get_year()."\n"; ?> Andreas Schmidt Übersicht Codegeneratoren 17/50 Fakultät IWI MDSD - SS 2014 Beispiel Inline Code Expansion <?php class Person { ... } class Film { private $title; private $year; private $director; function __construct($title,$year,$director) { $this->title = $title; $this->year = $year; $this->director = $director; } function get_title() { return $this->title; } function get_year() { return $this->year; } function get_director() { return $this->director; } } $p1 = new Person('Waits', 'Tom', '9.9.1949'); $f1 = new Film('Short Cuts', 1989, 'Jim Jarmusch'); echo "a little test:\n--------------\n"; echo $p1->get_name()." ".$p1->get_first_name()." ". $p1->get_day_of_birth()."\n"; echo $f1->get_title()." ".$f1->get_year()."\n"; Andreas Schmidt Übersicht Codegeneratoren 18/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Pattern Matching for Extended Syntax <class: Person (surame, first_name, date_of_birth) > zero or more whitespaces #<class:\s*(\w+)\s*\((.*)\)\s*># store content inside ( ) for later use Andreas Schmidt Übersicht Codegeneratoren 19/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Codefragment Inline Code Expander • inline-code-expander.php <?php look for a line with special syntax (extended language syntax) $lines = file($argv[1]); foreach ($lines as $line) { if (preg_match('#<class:\s*(\w+)\s*\((.*)\)\s*>#', $line, $match)) { $class_name = $match[1]; $att_list = preg_split("#\s*,\s*#", $match[2]); print_class_definition($class_name, $att_list); } else { print $line; } otherwise, do nothing (just output the line) } Andreas Schmidt Übersicht Codegeneratoren 20/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel: Regulärer Ausdruck $match[1] $match[2] /<class:\s*(\w+)\s*\((.*)\)\s*>/ <class: Person (name,vorname,geburtsdatum) > Andreas Schmidt Übersicht Codegeneratoren 21/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 function print_class_definition($class_name, $att_list) { ?> class <?php echo $class_name ?> { <?php foreach ($att_list as $a) { ?> private $<?php echo $a ?>; <?php } ?> function __construct(<?php echo join(",",add_dollar_sign($att_list)) ?>) { <?php foreach ($att_list as $a) { ?> $this-><?php echo $a ?> = $<?php echo $a ?>; <?php } ?> } <?php foreach ($att_list as $a) { ?> function get_<?php echo $a ?>() { return $this-><?php echo $a ?>; } <?php } ?> } <?php } Andreas Schmidt Übersicht Codegeneratoren 22/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Example Workflow $ php.exe inline-code-expander.php example-source.phpi > gen_ice.php $ php.exe gen_ice.php a little test: -------------Waits Tom 9.9.1949 Short Cuts 1989 Andreas Schmidt Übersicht Codegeneratoren 23/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 weiteres Beispiel ... Datei: literturliste.pls Datei: literaturliste.pl #! perl -w #! perl -w use strict; use DBI; use strict; use DBI; <fifdb:gehoim@literatur_db, select titel, autor from literatur> my $dbh = DBI->connect('dbi:Oracle:literatur_db', 'fifdb', 'gehoim' ) || die "Database connection not made: $DBI::errstr"; my $sql = "select titel, autor from literatur"; my $sth = $dbh->prepare( $sql ); $sth->execute(); while (my @row = $sth->fetchrow()) { print join(",", @row)."\n"; } $sth->finish(); $dbh->disconnect(); Andreas Schmidt Übersicht Codegeneratoren 24/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Mixed Code Generation • Eigenschaften: • Code als Input • „In Place“ Modifikation (Input Datei = Output Datei) • praktische Implementierung des Inline Code Expanders • „Special Markup“ (meist Kommentar) wird transformiert • Einsatzgebiete • wie Inline Code Expander • Erzeugung von get/set Methoden • Erzeugung von „Infrastrukturcode“ • ... Quellcode Mixed Code Generator Quellcode Compiler Executable Andreas Schmidt Übersicht Codegeneratoren 25/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel: Mixed Code Generation class person { protected $id; private $name; private $vorname; function __construct($id, $name, $vorname) class person { ... function get_id() { return $this->id; } { $this->id = $id; $this->name = $name; $this->vorname = $vorname; } // get($id) // get($name) // set($name) // set($vorname) // get($vorname) function get_name() { return $this->name; } function set_name($name) { $this->name = $name; } function set_vorname($vorname) { $this->vorname = $vorname; } function get_vorname() { return $this->vorname; } } Andreas Schmidt Übersicht Codegeneratoren 26/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Implementierung Beispiel • Implementation with regular expressions in perl (as command line tool) • call: perl -pi.bak transformation.pl source.php • file: transformation.pl • s#^(\s*)//\s*set\(\$(\w+)\)# $1function set_$2(\$$2) { $1 \$this->$2 = \$$2; $1}#; s#^(\s*)//\s*get\(\$(\w+)\)# $1function get_$2() { $1 return \$this->$2; $1}#; # # # # # Andreas Schmidt explanations: $1: indent (whitespaces) $2: name of variable \$: print a $-sign \(: matches a (-sign Übersicht Codegeneratoren 27/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Ersetzung mittels regulärere Ausdrücke // set($name) s#^(\s*)//\s*set\(\$(\w+)\)#$1function set_$2(\$$2) { $1 \$this->$2 = \$$2; $1}#; function set_name($name) { $this->name = $name; } Andreas Schmidt Übersicht Codegeneratoren 28/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Partial Class Generator Model • Funktionalität: • basiert auf explizitem Modell • generiert Reihe von Klassen • Manuelle Erweiterungen in abgeleiteten Klassen oder „protected areas“ • Ausgangspunkt für die Entwicklung eines „Tier Generators“ • Anwendungsbeispiele: • data access layer • Database scheme • User interfaces • Import/export filters Andreas Schmidt Übersicht Codegeneratoren 29/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Partial Class Generator Model Definition file (model) Partial Tier Generator Templates hand written source code Output Base Class source code Compiler Executable Andreas Schmidt Übersicht Codegeneratoren 30/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Modelldefinition # Definition of a simple Terra-Modell # $c = new MClass('Stadt'); $c->addAttribute('name'); $c->addAttribute('einwohner'); $c->addAttribute('lage'); $c->addAttribute('laenge'); $c->addAttribute('breite'); $classes[] = $c; $c = new MClass('Fluss'); $c->addAttribute('name'); $c->addAttribute('laenge'); $c->addAttribute('schiffbar'); $classes[] = $c; $c = new MClass('Berg'); $c->addAttribute('name'); $c->addAttribute('hoehe'); $c->addAttribute('erstbesteigung'); $classes[] = $c; Andreas Schmidt Übersicht Codegeneratoren 31/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Implementierung des Metamodells class MClass { public $name; public $attributes; function __construct($name) { $this->name = $name; } class MAttribut { public $name; function __construct($name) { $this->name = $name; } } function addAttribute($name) { $this->attributes[]=new MAttribut($name); } function attribute_names() { foreach ($this->attributes as $a) $names[] = '$'.$a->name; return $names; } } Andreas Schmidt Übersicht Codegeneratoren 32/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel Template <? include 'model.php'; ?> <? foreach ($classes as $class) { ?> class CRUD_<?= $class->name ?> { // instance variables <? foreach ($class->attributes as $a) { ?> private $<?= $a->name ?>; <? } ?> function __construct(<?= join(",", $class->attribute_names()) ?>) { <? foreach ($class->attributes as $a) { ?> $this-><?= $a->name ?> = $<?= $a->name ?>; <? } ?> } // the rest of the implementation follows here ;-) // ... (yes, here) <? } ?> Andreas Schmidt Übersicht Codegeneratoren 33/50 Fakultät IWI MDSD - SS 2014 generierter Code class CRUD_Stadt { // instance private private private private private variables $name; $einwohner; $lage; $laenge; $breite; function __construct($name,$einwohner,$lage,$laenge,$breite) { $this->name = $name; $this->einwohner = $einwohner; $this->lage = $lage; $this->laenge = $laenge; $this->breite = $breite; } // the rest of the implementation follows here ;-) // ... (yes, here) } class CRUD_Fluss { // instance private private private variables $name; $laenge; $schiffbar; function __construct($name,$laenge,$schiffbar) { $this->name = $name; $this->laenge = $laenge; $this->schiffbar = $schiffbar; } Andreas Schmidt Übersicht Codegeneratoren 34/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Erweiterung um Applikationslogik • Integration der Applikationslogik in Unterklassen class Stadt extends CRUD_Stadt { //Application logic comes here ... } class Fluss extends CRUD_Fluss { //Application logic comes here ... } • Template für Stubs # Stub generator for the application classes <? foreach ($classes as $class) { ?> class <?= $class->name ?> extends CRUD_<?= $class->name ?> { //Application logic comes here ... } <? } ?> class Berg extends CRUD_Berg { //Application logic comes here ... } Andreas Schmidt Übersicht Codegeneratoren 35/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Tier Generator Model • Eigenschaften • Wird aus abstraktem Modell generiert • Erstellt den kompletten Code einer Schicht (Tier) • Prinzip analog Partial Class Generator • Einsatzgebiete • Datenbankzugriffsschicht • Web Client Layer • Data Import/Export • ... Definition file (model) Templates Tier Generator Output Base Class source code Compiler Executable Andreas Schmidt Übersicht Codegeneratoren 36/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Tier Generator Model • Unterschied zu Partial Class Generator: • Erzeugt den kompletten Code einer Anwendungsschicht • Gesamte Applikationslogik liegt außerhalb der „Codebase“ • Validierung der Applikationslogik durch Domänenexperten möglich • Durch Änderung der Templates kann die gesamte Anwendung auf eine andere Plattform portiert werden • Partial Class Generator ist sehr guter Ausgangspunkt für die Implementierung eines Tier generators • Partial Class Generator folgt der 80/20 Prozent Regel 80% des Codes werden vom Partial Class Generator erzeugt 20% des Codes in abgeleiteten Klassen manuell erstellt. • Full Tier Generator ist dann später auch für die letzten 20% des Codes verantwortlich Andreas Schmidt Übersicht Codegeneratoren 37/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Domänenspezifische Sprachen • Eigenschaften: • Eigene Sprache für spezielles Anwendungsgebiet • Dient zur Implementierung der Geschäftslogik • Werkzeuge zur Erstellung von DSL: • Lexikalische Analyse: LEX, FLEX • Programmgeneratoren (legen Grammatik fest): YACC, BISON, ANTLR • Beispiele: • Mathematica • SQL • make, ant (werden in Vorlesung nicht weiter verfolgt !) Andreas Schmidt Übersicht Codegeneratoren 38/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Code Generierungs Workflow • Traditionelle Softwareentwicklung • Softwareentwicklung mit Generator Edit Templates Edit Edit Generate Compile Compile Test Test Andreas Schmidt Übersicht Codegeneratoren 39/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Exkurs: reguläre Ausdrücke • Mächtige Sprache zur Beschreibung von Textmustern • in vielen Sprachen (PHP, Perl, Java, ...), Werkzeugen (sed, grep, awk, ...) und Editoren (vi, emacs, ...) implementiert • Sonderzeichen: • Die meisten zeichen repräsentieren sich selbst, es gibt jedoch eine Reihe von Zeichen mit Sonderbedeutung: \ | ( ) [ ]{} ^ $ * + ? . / • Soll nach einem dieser Zeichen im Text gesucht werden, so muss ihnen ein Backslash \ vorangestellt werden, z.B. \$ für die Suche nach einem Dollarzeichen • Bedeutungen der Sonderzeichen siehe nächste Folie • reguläre Zeichen werden i.a. durch das /-Zeichen eingeschlossen, z.B. /MDSD/ Andreas Schmidt Übersicht Codegeneratoren 40/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Zeichen Bedeutung Beispiel ^ Anfang der Zeichenkette ^Hallo: Zeichenkette, die mit dem Wort ’Hallo’ beginnen $ Ende der Zeichenkette Amen$: Zeichenkette, die mit dem Wort ’Amen’ endet . beliebiges Zeichen (außer Zeilenumbruch) X.L: Zeichenketten wie ’XML’, ’XSL’, ’X4L’, ’X!L’, ’X.L’. [] Zeichenklasse: Passt auf genau ein Zeichen im Text. Um welche Zeichen es sich handelt wird innerhalb der Klammer spezifiziert. [AEIOUaeiou]: Passt auf alle Vokale [A-Z]: Passt auf alle Großbuchstaben [^A-Z]: alle Zeichen die keine Großbuchstaben sind [-_]: Die Zeichen - und _ Es gibt eine Reihe von bereits vordefinierten Zeichenklassen (siehe weiter unten) * Wiederholung: der links vom Zeichen stehende Ausdruck, kann null bis n-mal auftreten (habgierig) + Wiederholung: der links vom Zeichen stehende Ausdruck, kann ein bis n-mal aufreten (habgierig) ? Optional: der links vom Fragezeichen stehende Ausdruck kann, muss aber nicht vorkommen Andreas Schmidt A*: ’’, ’A’, ’AA’, ’AAA’, ... [a-z]*: Zusammenhängende Kette von null bis n Kleinbuchstaben .*: alles -?[0-9]+: Eine Zahl, die sowohl positiv als auch negativ sein kann Übersicht Codegeneratoren 41/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 *? Wiederholung: der links vom Zeichen stehende Ausdruck, kann null bis n-mal auftreten (nicht habgierig) +? Wiederholung: der links vom Zeichen stehende Ausdruck, kann ein bis n-mal aufreten (nicht habgierig) | Alternative A|a: entweder ’A’ oder ’a’ () Gruppierung/Speicher: Grupiert n-Zeichen, speichert den Inhalt der Klammer in Variable ($1, $2, ...) Tel: ([-/ 0-9]) : Speichert die Telefonnummer (bestehnd aus den Zeichen 0-9, Leerzeichen sowie ’-’ und ’/’) in der Variable $1 (bzw. \1) (Herr|Frau) : Entweder ’Herr’ oder ’Frau’ ([0-9]+),\1 : passt, wenn eine Zahl zweimal (durch Komma getrennt) hintereinander steht {<min>[, [<max>]]} Kardinalität: Der Ausdruck links der öffnenen Klammer musss mindestens <min>-mal Auftreten und maximal <max>-mal. Andreas Schmidt A*: ’’, ’A’, ’AA’, ’AAA’, ... [a-z]*: Zusammenhängende Kette von null bis n Kleinbuchstaben .*: alles [0-9]{3-5} : drei bis fünfstellige Zahlen [0-9]{5} : Fünfstellige Zahlen x{10,}: mindestens zehn mal ’x’ Übersicht Codegeneratoren 42/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 \s Leerzeichen: passt auf <Space>, <TAB>. <Return>, <FormFeed>, ^\s*#.*: passt auf Zeilenkommentare (z.B. in PHP, Perl) \w Wortzeichen, Buchstaben, Zahlen und Underline (_) \w+ \S Negation von \s \W Negation von \w \b Wortgrenze (0 Zeichen) Andreas Schmidt \bdie\b: ’ die ’ aber nicht ’ diebisch’ Übersicht Codegeneratoren 43/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiele zu regulären Ausdrücken • IP-Adressen (142.52.44.113) #(\d{1,3}\.){3}\d{1,3}# • Suche nach Ski (nicht Skilift, Skiunfall, Skipetaren) #\bSki\b# • keine Vokale #[^aeiouAEIOU]# • Addition zweier Zahlen (124124 + 35235) \d+\s*\+\s*\d+ • Entfernen von <script>...</script> Abschnitten aus HTML-Text #<script>.*?</script># • Alles zwischen <a> ... </a>, <b>...</b> und <c>...</c> entfernen: #<([abc])>.*?</$1># Andreas Schmidt Übersicht Codegeneratoren 44/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Unterschied zwischen .* und .*? : • zu durchsuchender Text: "367", "Neckar", "Rhein", "Villingen-Schwenningen","Mannheim" • Pattern1: /".*"/ passt auf komplette Zeichenkette • Pattern2: /".*?"/ passt auf "367" Merkregel: .* ist habgierig (soviel wie möglich) .*? ist nicht habgierig (sowenig wie möglich) Andreas Schmidt Übersicht Codegeneratoren 45/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Substitution mit regulären Ausdrücken • s/<Suchmuster>/<Ersetzungsmuster>/ • Beispiele: s/Schmitt/Schmidt/ : ersetzt vorkommen von ’Schmitt’ durch ’Schmidt’ s/(-?[0-9]+),([0-9]{2})/$1.$2/ : Ersetzt in Geldbeträgen das Komma durch einen Punkt (amerikanische Schreibweise) s/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/xxx.xxx.xxx.xxx/ : anonymisiert IP-Adressen s/<.*?>// : entfernen von Markup Andreas Schmidt Übersicht Codegeneratoren 46/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Reguläre Ausdrücke und Perl • Aufrufe von Kommandozeile • Ausgabe auf STDOUT perl -p -e ’s/Ski/Snowboard/g’ reisebericht.txt • Modifikation der Inputdatei (inkl. Erstellung Backupdatei - Endung .bak) perl -pi.bak -e ’s/nähmlich/nämlich/g’ entschuldigung.txt • Substitutionsregeln in externer Datei (ersetzungen.pl) perl -pi.old ersetzungen.pl *.doc • Inhalt Datei ersetzungen.pl: s/mfg/mit freundlichen Grüßen/; s/Tel(efon)?\s*:\s*0?([\s\d]{5,12})/Telefon: +49 $2/; Andreas Schmidt Übersicht Codegeneratoren 47/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • Datumskonvertierung (2008-3-20 -> 20.3.2008): $ perl -pi.bak -e 's/\b(\d{4})-(\d{2})-(\d{2})/$3.$2.$1/' inserts.sql Andreas Schmidt Übersicht Codegeneratoren 48/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Regex Modifikatoren • • • • i (Ignore case): Groß-/Kleinschreibung ignorieren s: Metzeichen ’.’ passt auch auf Zeilenumbruch g (Global): Findet/ersetzt alle Vorkommen m (Multiline): ’^’und ’$’ passen auf jeden Zeilenbeginn/jedes Zeilenende Beispiele: • Jede zweite Spalte auslesen: /^\d+(\d+)/m • Global ä durch &auml; erstzen s/ä/&auml;/g • (mehrzeilige) Programmkommentare entfernen s#/\*.*?\*/##s Andreas Schmidt Übersicht Codegeneratoren 49/50 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Ressourcen • Regular Expression Tutorial: http://www.regular-expressions.info/tutorial.html • „The Mechanics of Expression Processing“: Onlinekapitel aus dem Buch „mastering regular expressions“ von Jeffrey Friedl: http://www.oreilly.de/catalog/regex/chapter/ch04.html Andreas Schmidt Übersicht Codegeneratoren 50/50