Zeichenmengen für reguläre Ausdrücke generieren
von Gumbo
am 05.06.08 um 17:37 (745 Hits)
Ich habe mal wieder aus Ärger darüber, immer wieder Zeichenmengen für reguläre Ausdrücke aus einer vorgegebene Menge von Zeichen per Hand erstellen zu müssen, eine Hilfsfunktion geschrieben.
Die Anwendung ist denkbar simpel: einfach eine Zeichenkette der Zeichen angeben, die zu einer Zeichenmenge zusammengefasst werden sollen:PHP-Code:function preg_createCharacterSet($chars, $complement=false, $basicSet=null)
{
$retVal = '';
$sc = implode('', array_merge(range("\x00", "\x20"), array("\x2D", "\x5B", "\x5C", "\x5D"), range("\x7F", "\xFF")));
if (!is_string($chars)) {
return false;
}
$chars = array_unique(unpack('C*', $chars));
sort($chars);
if ($complement) {
if (!is_string($basicSet)) {
$charRange = range(0, 127);
} else {
$charRange = array_unique(unpack('C*', $basicSet));
}
$chars = array_diff($charRange, $chars);
$chars = array_values($chars);
}
$count = count($chars);
for ($i=0, $char=null; $i<$count; $i++) {
$char = $chars[$i];
if (strpos($sc, $char)!==false) {
$range = sprintf('\\x%02x', $char);
} else {
$range = chr($char);
}
for ($j=1; $j<$count-$i; $j++) {
if (($char+$j)!=$chars[$i+$j]) {
break;
}
}
$j--;
if ($char!=$chars[$i+$j]) {
$i += $j;
$char = $chars[$i];
if (strpos($sc, $char)!==false) {
$range .= '-'.sprintf('\\x%02x', $char);
} else {
$range .= '-'.chr($char);
}
}
$retVal .= $range;
}
return $retVal;
}
Um das Komplement zu erhalten, einfach den zweiten Parameter auf true setzen:PHP-Code:$regexp = '['. preg_createCharacterSet("()<>@,;:\\\"/[]?={} \t").']';
Mit dem dritte Parameter kann die Grundmenge für das Komplement angegeben werden. Der Standardwert ist der ASCII-Zeichensatz.PHP-Code:$regexp = '['. preg_createCharacterSet("()<>@,;:\\\"/[]?={} \t", true).']';
Wozu das nützlich ist, möchte ich euch an folgendem Beispiel verdeutlichen, indem ein regulärer Ausdruck für den „quoted-string“ Token (siehe RFC 822) erzeugt wird:PHP-Code:// ; ( Octal, Decimal.)
// CHAR = <any ASCII character> ; ( 0-177, 0.-127.)
$CHAR = implode('', range("\x00", "\x7F"));
// quoted-pair = "\" CHAR ; may quote any char
$quotedPair = '(?:\x5C['.preg_createCharacterSet($CHAR).'])';
// qtext = <any CHAR excepting <">, ; => may be folded
// "\" & CR, and including
// linear-white-space>
$qtext = '(?:['.preg_createCharacterSet("\"\\\r", true, $CHAR).'])';
// quoted-string = <"> *(qtext/quoted-pair) <">; Regular qtext or
// ; quoted chars.
$quotedString = '"(?:'.$qtext.'|'.$quotedPair.')*"';






