Estoy tratando de recorrer el resultado de preg_match_all() y reemplazar las coincidencias.
Lo que estoy tratando de lograr es extraer todas las apariciones en un texto que está entre corchetes con un signo de dólar al frente, y luego crear un <span> con una identificación que es el contenido dentro de los corchetes.
Entonces, en el siguiente ejemplo del texto "Trabajando de ${spa_open_time} a ${spa_close_time} todos los días", debo extraer ${spa_open_time} y ${spa_close_time} y reemplazarlos en el texto con <span> .
el resultado esperado
Working from <span id="tag_spa_open_time">${spa_open_time}</span> to <span id="tag_spa_close_time">${spa_close_time}</span> every dayAquí está el código que se me ocurrió hasta ahora
$text = 'Working from ${spa_open_time} to ${spa_close_time} every day'; $result = preg_match_all('/(\$\{\w+\})/', $text, $positive_catch); if ($result > 0) { foreach ($positive_catch as $catch) { if (is_array($catch)) { foreach ($catch as $key => $ivalue) { $fvalue = str_replace("\${", "", $ivalue); $fvalue = str_replace("}", "", $fvalue); $replace = '<span id="tag_'.$fvalue.'">'.$ivalue.'</span>'; $str = str_replace($catch,$replace,$text); } } } } else { $str = $text; } echo $str;Y el resultado actual es
Working from <span id="tag_spa_close_time"><span id="tag_spa_close_time">${spa_close_time}</span></span> to <span id="tag_spa_close_time">${spa_close_time}</span> every dayEstoy haciendo algo mal, pero no puedo entender cuál es el problema. Aquí está el código en acción http://sandbox.onlinephpfunctions.com/code/31894399fd981fb791c587fa04c68581c4945b6d
Modifiqué su expresión regular para devolver las cadenas para buscar (p. ej., "${spa_open_time}") y las "claves" (p. ej., "spa_open_time"). Luego recorro esas matrices al mismo tiempo y genero un par de cadenas de búsqueda y reemplazo que aplico a $str , que se modifica cada vez. Al final del ciclo, $str contiene tus resultados.
$str = $text = 'Working from ${spa_open_time} to ${spa_close_time} every day'; $result = preg_match_all('/\$\{(\w+)\}/', $text, $positive_catch); if ($result > 0) { for ( $i=0; $i < sizeof($positive_catch[0]); $i++ ) { $search = $positive_catch[0][$i]; $key = $positive_catch[1][$i]; $replace = '<span id="tag_' . $key . '">' . $search . '</span>'; $str = str_replace($search, $replace, $str); } } else { $str = $text; } echo $str;`
Si necesita hacer varios reemplazos, usar preg_replace_callback() es más fácil y más confiable que recorrer los resultados de un preg_match_all() con str_replace() .
$text = 'Working from ${spa_open_time} to ${spa_close_time} every day'; $text = preg_replace_callback('/(\$\{\w+\})/', function($match) { // Removing the leading and trailing characters for class name: $fvalue = substr($match[1], 2, -1); // Returning the match (your $ivalue) wrapped in a span-tag: return '<span id="tag_'.$fvalue.'">' . $match[1] . '</span>'; }, $text); Esto devuelve el resultado que esperas. Si no hay coincidencias, la cadena $text permanece como está.
Aquí, preg_replace_callback coincide con todas las instancias de su expresión regular y le permite transformar las coincidencias y devolverlas "en el lugar", sin tener que buscar/reemplazar por separado sobre su cadena. Luego, cualquier reemplazo ocurrirá exactamente donde debería, lo cual no es un hecho con operaciones de reemplazo de cadenas más complejas.
Puede usar un grupo de captura \${(\w+)}/ alrededor de los caracteres de la palabra, que se devolverá como el segundo elemento de la matriz de coincidencias cuando use preg_replace_callback .
El partido completo es el primer elemento en los partidos.
Tenga en cuenta que no tiene que escapar de los rizados en el patrón.
$text = 'Working from ${spa_open_time} to ${spa_close_time} every day'; $text = preg_replace_callback('/\${(\w+)}/', function($matches) { return sprintf('<span id="tag_%s">%s</span>',$matches[1], $matches[0]); }, $text); echo $text;Producción
Working from <span id="tag_spa_open_time">${spa_open_time}</span> to <span id="tag_spa_close_time">${spa_close_time}</span> every dayVea una demostración de PHP .