Kopfbereich

Direkt zum Inhalt Direkt zur Navigation Direkt zum Kontakt

Inhalt

Reguläre Ausdrücke

1. Reguläre Ausdrücke (regular expressions, regex)

1.1. PHP

1.1.1. BB-Codes

  // Ziel: Wenn www ohne http:// davor, dann http:// davorsetzen,
// damit daraus mit dem RegEx unten ein Link wird.
// Zeilenwechsel und "www." ersetzen durch Zeilenwechsel und "http://www."
// Leerzeichen und "www." ersetzen durch Leerzeichen und "http://www."
$strText = preg_replace("#(<br>|\s)www\.#is", "\\1http://www.", $strText);
// "www." am Zeilenanfang durch "http://www." ersetzen
$strText = preg_replace("#^(www\.)#is", "http://\\1", $strText);
// BB-Codes:
$strText = preg_replace("#\[b\](.+?)\[/b\]#is", "<B>\\1</B>", $strText); // <b>
$strText = preg_replace("#\[i\](.+?)\[/i\]#is", "<I>\\1</I>", $strText); // <i>
$strText = preg_replace("#\[u\](.+?)\[/u\]#is", "<U>\\1</U>", $strText); // <u>
// '#(^|[^\"=]{1})(http://|ftp://|mailto:|news:)([^\s<>]+[^,;:\.!\?])([[,;:\.!\?\s\n<>]{1}|$)#sm'
//
// 1. Gruppe:
// Zeilenanfang (^) oder (|) ein einzelnes Zeichen ({1}), das nicht " oder = ist ([^\"=])
//
// 2. Gruppe:
// eines von 4 Protokollbezeichnungen
//
// \s any whitespace character, irgendein Leerzeichen-Zeichen
//
// 3. Gruppe
// ein oder mehr Zeichen (+), das nicht (^) Leerzeichen, 'spitze Klammer auf' oder 'spitze Klammer zu' ist
// gefolgt von einem Zeichen, das nicht ,;:.!?) ist
//
// 4. Gruppe
// ein einzelnes Zeichen: ,;:.!? oder Leerzeichen, Zeilenwechsel, 'spitze Klammer auf' oder 'spitze Klammer zu' oder
// Zeilenende ($)
//
// m (PCRE_MULTILINE)
//
// By default, PCRE treats the subject string as consisting of
// a single "line" of characters (even if it actually contains
// several newlines). The "start of line" metacharacter (^)
// matches only at the start of the string, while the "end of
// line" metacharacter ($) matches only at the end of the
// string, or before a terminating newline (unless D modifier
// is set). This is the same as Perl. When this modifier is
// set, the "start of line" and "end of line" constructs match
// immediately following or immediately before any newline in
// the subject string, respectively, as well as at the very
// start and end. This is equivalent to Perl's /m modifier. If
// there are no "\n" characters in a subject string, or no
// occurrences of ^ or $ in a pattern, setting this modifier
// has no effect.
//
// s (PCRE_DOTALL)
//
// If this modifier is set, a dot metacharater in the pattern
// matches all characters, including newlines. Without it,
// newlines are excluded. This modifier is equivalent to Perl's
// /s modifier. A negative class such as [^a] always matches a
// newline character, independent of the setting of this
// modifier.
// Original: $p = '#(^|[^\"=]{1})(http://|ftp://|mailto:|news:)([^\s<>]+)([\s\n<>]|$)#sm';
$p = '#(^|[^\"=]{1})(http://|ftp://|mailto:|news:)([^\s<>]+[^,;:\.!\?\)])([[,;:\.!\?\)\s\n<>]{1}|$)#sm';
// Test: $strText = preg_replace($p,"Gruppe 1:#\\1#, Gruppe 2:#\\2#, Gruppe 3:#\\3#, Gruppe 4:#\\4#", $strText);
$strText = preg_replace($p,"\\1<A HREF=\"\\2\\3\">\\2\\3</A>\\4", $strText);

1.1.2. valide (gültige) E-Mail-Adresse

// E-Mail:
// Erlaubte Zeichen zu Beginn: Buchstaben, Zahlen, Unterstrich, Minus, Punkt
// Klammeraffe
// Erlaubte Zeichen nach Klammeraffe: Buchstaben, Zahlen, Minus
// Punkt
// Top Level Domain aus 2 bis 4 Buchstaben
//
// $_POST['email'] => $email
if (isset($email) &&
(!empty($email)) &&
($email!="@") &&
(!preg_match("/^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4}|museum$/i", $email))) {
$strErrMsg[] = "Die E-Mail-Adresse enthält ungültige Zeichen.";
}

1.1.3. Mail-Formular-Check mit [:print:] und [:space:]

Zitat: "[:print:] ist eine Posix-Zeichenklasse (POSIX: Portable Operating System Interface), die alle möglichen druckbaren Zeichen enthält, also Buchstaben, Ziffern, Leerzeichen und Interpunktion. [:space:] erlaubt zusätzlich noch Zeilenumbrüche und Tabulatoren. Damit das Skript Umlaute und Buchstaben wie ß oder ä passieren lässt, fügt man oben die setlocale-Zeile ein."

Quelle mit Erklärung, wie ein E-Mail-Formular vor Angriffen geschützt werden kann:

Mail-Formulare auf Webseiten absichern

Auszug:

setlocale(LC_ALL, 'de_DE');
$pruefung = array(
'absender' => '/^[\w.+-]{2,}\@[\w.-]{2,}\.[a-z]{2,6}$/',
'betreff' => '/^[[:print:]]{3,}$/',
'text' => '/^[[:print:][:space:]]{10,}$/'
);
foreach($_POST as $parameter => $wert) {
if(isset($pruefung[$parameter])) {
if(!preg_match($pruefung[$parameter], $wert))
die('Probleme mit Feld ' . $parameter .': ' . $wert);
} else {
unset($_POST[$parameter]);
}
}

Alle Post-Parameter werden durchlaufen: "parameter" ist der Schlüssel des assoziativen Arrays, also der Feldname. "wert" ist der Inhalt des Felds. Die Zeichenmenge aus Buchstaben, Ziffern und Unterstrich wird mit \w beschrieben.

1.2. Java-Script

1.2.1. globales Ersetzen eines Zeilenwechsels

 // regulaerer Ausdruck: g bedeutet: globales Suchen/Ersetzen;
alert('" + strGlobalAlert.replace(/\n/g,"\\n").replace(/\'/g,"\\'") + "')");

1.3. grep

1.4. htaccess

1.5. Vergleich der Schreibweise der regulären Ausdrücke

Quelle: Zeitschrift c't

grep, sed GNU grep, sed egrep GNU egrep perl
Platzhalter
ein beliebiges Zeichen . . . . .
ein Zeichen aus einer Liste [] [] [] [] []
Umkehrung der Liste [Zirkumflex] [Zirkumflex] [Zirkumflex] [Zirkumflex] [Zirkumflex]
Ziffern [0-9] [0-9] [0-9] [0-9] \d oder [0-9]
Wiederholungen
beliebig viele, auch keins * * * * *
beliebig viele, mindestens eins \+ + + +
eins oder keins \? ? ? ?
genau n \{n\} {n} {n}
n oder mehr \{n,\} {n,} {n,}
n bis m \{n,m\} {n,m} {n,m}
Anker
Zeilenanfang Zirkumflex Zirkumflex Zirkumflex Zirkumflex Zirkumflex
Zeilenende $ $ $ $ $
Wortanfang \< \<
Wortende \> \>
Wortanfang oder -ende \b \b \b
Anderes
oder \| | | |
Gruppierung \(\) \(\) () () ()
Inhalt der ersten Klammer \1 \1 \1 \1 oder $1
Sonderzeichen suchen \ \ \ \ \

1.6. Beispiele mit regulären Ausdrücken für PHP

1.6.1. Definition einiger Muster

// pattern for php code:
define('REG_EX_PHP_CODE', '#(<\?php|<\?)(.*?)\?>#si');
// pattern for html tags:
define('REG_EX_HTML_CODE', '#<[\/\!]*?[^<>]*?>#si');
// pattern for general bb code:
define('REG_EX_BBCODE', '#\[*?[^\[\]]*?\]#si');
// pattern for several (consecutive) spaces, at least 2 spaces
define('REG_EX_SPACES', '#\s{2,}#si');
// pattern for a html entity e.g. ä
define('REG_EX_HTML_ENTITY', '#&(?!(\#[\d]{2,4};|[a-z\d]{2,6};))#i');

1.6.2. Anwendung der Muster

Leerzeichen-Behandlung:

// replace several consecutive spaces by one space
preg_replace(REG_EX_SPACES, ' ', $text);

Umwandlung einer HTML-Seite mit Umlauten:

// use htmlentitites() only for text
// without html tags and without html entities
function fct_html_entities($text) {
$output = array();
$result1 = preg_split('/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
// text:, i = 0, 2, 4, ... (even)
// html tag: i = 1, 3, 5, ... (odd)
$even1 = 1; // 1: true, 0: false
for($i=0; $i<count($result1); $i++) {
if ($result1[$i]) {
if ($even1) {
$even2 = 1; // 1: true, 0: false
$result2 = preg_split('/(&\#[\d]{2,4};|&[a-zA-Z\d]{2,6};)/U', $result1[$i], -1, PREG_SPLIT_DELIM_CAPTURE);
// text:, j = 0, 2, 4, ... (even)
// html entity: j = 1, 3, 5, ... (odd)
for($j=0; $j<count($result2); $j++) {
if ($result2[$j]) {
$output[] = ($even2) ? htmlentities($result2[$j]) : $result2[$j];
}
$even2 = 1 - $even2;
}
} else {
$output[] = $result1[$i]; // HTML tag
}
}
$even1 = 1 - $even1;
}
return implode('',$output);
}

Umwandlung variabler PHP-Informationen in statisches HTML:

Das Muster REG_EX_PHP_CODE ist oben definiert.

// function converts php-html-mix to html-code without php
function make_html_code($code) {
preg_match_all(REG_EX_PHP_CODE, $code, $raw_php_matches);
foreach($raw_php_matches[0] as $match) {
$raw_php_str = str_replace(array('<?php','?>'),'',$match);
ob_start();
eval("$raw_php_str;");
$exec_php_str = ob_get_contents();
ob_end_clean();
// last value 1: limit, only one replace
$code = preg_replace(REG_EX_PHP_CODE, $exec_php_str, $code, 1);
}
return $code;
}

Umwandlung von Umlauten in Buchstaben ohne diakritische Zeichen:

// converts é to e, ä to a etc. (umlauts without diacritical signs)
// reg ex \&(.)[^;]*; matches for instance ä
preg_replace('/\&(.)[^;]*;/', '\\1', htmlentities($text));

1.7. Links zum Thema RegEx

Hier werden vornehmlich reguläre Ausdrücke für den E-Mail-Client "The Bat!" (TB) behandelt:

Regenechsen-RegEx-Kurs

1.8. Beispiele mit TextPad

1.8.1. HTML-Formatierung

Der Texteditor TextPad ermöglicht Suchen und Ersetzen mit regulären Ausdrücken. Möchte man eine Gruppe bilden, müssen die Klammern mit einem vorangestellten Backslash verwendet werden. Das Suchmuster im Ersetzen-String wird mit \1 usw. angegeben werden.

 <div class="xxx">
123
</div>
soll mit variablem Klassennamen und variablem Text ersetzt werden durch
<div class="xxx">123</div>

Man kann das mit zwei Ersetzungen nacheinander lösen:

Suchen nach:    \(<div[^>]*>\) *\n +
Ersetzen durch: \1
Suchen nach: \n +\(</div>\)
Ersetzen durch: \1

In der ersten Ersetzung soll nach div kein Größer-Als-Zeichen folgen. Das Muster endet mit dem Größer-Als-Zeichen. Und danach folgen noch beliebig viele Leerzeichen, ein Zeilenwechsel und mindestens 1 Leerzeichen.

1.8.2. Link-Liste in HTML umwandeln

In einer Text-Datei stehen untereinander URLs.

vorher:  http://www.spiegel.de
nachher: <a class="extLink" href="http://www.spiegel.de" target="_blank">http://www.spiegel.de</a>
Suchen nach: \(.+?\)\n
Ersetzen durch: <a class="extLink" href="http://\1" target="_blank">\1</a>

Die Gruppe des Suchmusters enthält beliebige Zeichen mindestens ein Mal, wobei der Suchausdruck "nicht gierig" ist.

1.8.3. Ergänzung von Links

Für das Wiki sollen RFCs verlinkt werden. Nur die RFC-Nummer ist variabel.

vorher:  RFC1945
nachher: [http://rfc.net/rfc1945.html RFC1945]
Suchen nach: RFC\([0-9]\{3,4\}\)
Ersetzen durch: [http://rfc.net/rfc\1.html RFC\1]

Die Gruppe des Suchmusters besteht aus 3 oder 4 Ziffern hinter dem Begriff RFC.

1.8.4. Programm-Code-Änderung

vorher:  $template_query->RecordCount() > 0
nachher: !$template_query->EOF
Der Objektname ist variabel.
Suchen nach: $\([a-zA-Z0-9_]+\)->RecordCount\x28\x29\x20\x3e\x200
Ersetzen durch: \!\$\1->EOF

Die Gruppe des Suchmusters besteht aus Buchstaben, Zahlen und Unterstrich. Sonderzeichen wie z.B. geöffnete Klammer werden hexadezimal codiert.

1.8.5. Steuerdatei-Änderung

In einer Steuerdatei soll nach einer Raute das Datum angefügt werden, wenn ein Datum in den Dateinamen codiert wurde.

vorher:  2005_06_26_-heidelberg-(34).jpg #
nachher: 2005_06_26_-heidelberg-(34).jpg # 26.06.2005
Suchen nach: \([0-9]\{4\}\)_\([0-9]\{2\}\)_\([0-9]\{2\}\)\(.*?\) #
Ersetzen durch: \1_\2_\3_\4 # \3\.\2\.\1

Die Bestandteile des Datums Jahr (1), Monat (2) und Tag (3) werden in Gruppen festgehalten. Der restliche Dateiname ist die 4. Gruppe.