register_printf_function in PHP
Frage
Ich muss dem Benutzer erlauben, ein benutzerdefiniertes Format für eine Funktion anzugeben, die vsprintf verwendet, und da PHP nicht über glibc' register_printf_function() verfügt, muss ich es mit PCRE tun.
Meine Frage ist: Was wäre der beste REGEXP, um % gefolgt von einem beliebigen Zeichen zu finden und nicht % davor zu haben, und zwar auf eine brauchbare Weise für die anschließende programmatische Verwendung?
Die nächstgelegene Lösung, die ich finden konnte, war:
<?php
function myprintf($format,$args) {
$matches = array();
preg_match_all('/((?<!%)%*[^%]+)/', $format,$matches,PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER);
print_r($matches);
}
myprintf("begin%a%%b%%%c%d",NULL);
Was irgendwie funktioniert, ABER es wird durch Eingaben wie „%%%c“ „verwirrt“.Ich hätte gerne eine Reihe von zwei %-Zeichen (also Escapezeichen) in einer Gruppierung, wie zum Beispiel:
Array (
0 => '%%',
1 => '%c'
)
und nicht so, als würde es es jetzt tun:Array (0 => '%%% C') Das heißt, ich muss die Eingabe intakt halten, obwohl sie tokenisiert sind, um die Teile zusammenzuschließen, nachdem ich die benutzerdefinierten Printf -Formate, auf die ich in der Eingabe begegnet bin, verarbeitet habe.
Danke,
Flavius
PS:Der „Benutzer“ ist eigentlich ein anderer Programmierer.Ich bin mir der Auswirkungen auf die Sicherheit bewusst.
Lösung
Code:
$string = "begin%a%%b%%%c%d";
preg_match_all('/([^%]|%%)+|%.*?[a-zA-Z]/', $string, $matches);
print_r($matches[0]);
Ausgabe:
Array
(
[0] => begin
[1] => %a
[2] => %%b%%
[3] => %c
[4] => %d
)
Dies sollte zusammengesetzte Formatspezifizierer wie analysieren %.3f
oder %$1d
auch richtig, auch.
Andere Tipps
Wenn Sie ein % gefolgt von einem Buchstaben oder einem anderen % wünschen, können Sie einfach Folgendes tun:
$string = "begin%a%%b%%%c%d";
preg_match_all("/%./", $string, $matches);
$values = $matches[0];
// $values = array(5) { [0]=> string(2) "%a" [1]=> string(2) "%%" [2]=> string(2) "%%" [3]=> string(2) "%c" [4]=> string(2) "%d" }
// begin %a %% b %% %c %d <- is the string with spaces.
Bearbeiten:
Ich denke, das entspricht dem, was Sie in den Kommentaren unten erwarten:
preg_match_all('/(\s?\w+\s?|%[^%]|%%)/', $string, $matches);
$value = $matches[0];
// $value = array(7) { [0]=> string(5) "begin" [1]=> string(2) "%a" [2]=> string(2) "%%" [3]=> string(1) "b" [4]=> string(2) "%%" [5]=> string(2) "%c" [6]=> string(2) "%d" }
Der Hauptunterschied besteht darin [2]=> string(3) "%%b"
wird [2]=> string(2) "%%" [3]=> string(1) "b"
was Ihnen die gleichen Ergebnisse liefern sollte, weil die %%
würde als Single gewertet werden %
wie auch immer.