Pregunta

Necesito que el usuario especifique un formato personalizado para una función que utiliza vsprintf, y ya que PHP no tiene glibc' register_printf_function(), voy a tener que hacerlo con PCRE.

Mi pregunta es, ¿cuál sería la mejor REGEXP para que coincida %, seguido de cualquier carácter y no tener % antes de que, en una forma utilizable para el uso programático después?

La solución más cercano que pudimos conseguir fue:

<?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);

Que un poco de obras, PERO este se "confunde" por entradas como "%%%c".Me gustaría tener la serie de dos %-signos (es decir, se escapó) en un solo grupo, como:

Array (
 0 => '%%',
 1 => '%c'
)

y no como se está haciendo ahora:Array ( 0 => '%%%c' ) Es decir, que se necesita para mantener la entrada intacta, a pesar de símbolo (token), con el fin de unir los trozos juntos después de hacer el procesamiento de la costumbre printf formatos que me encuentro en la entrada.

Gracias,

Flavio

PS:el "usuario" es en realidad otro programador.Soy consciente de las implicaciones de seguridad.

¿Fue útil?

Solución

Código:

$string = "begin%a%%b%%%c%d";
preg_match_all('/([^%]|%%)+|%.*?[a-zA-Z]/', $string, $matches);
print_r($matches[0]);

Salida:

Array
(
    [0] => begin
    [1] => %a
    [2] => %%b%%
    [3] => %c
    [4] => %d
)

Esto debería analizar especificadores de formato compuesto como %.3f o %$1d adecuadamente, así, también.

Otros consejos

Si lo que quieres es un% seguido de una letra u otra%, entonces solo puede hacer:

$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. 

Editar

Creo que esto es equivalente a lo que quiere de los comentarios a continuación:

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" }

La diferencia principal es que se convierte en [2]=> string(3) "%%b" [2]=> string(2) "%%" [3]=> string(1) "b" que deben dar los mismos resultados debido a que el %% sería evaluada como una sola % de todos modos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top