Ver Mensaje Individual
  #4 (permalink)  
Antiguo 10/10/2014, 15:42
Avatar de Alexis88
Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Función para extraer y usar texto de un string

Probablemente exista otra forma más eficiente de hacer esto, pero se me ocurre hacerlo así:

Código PHP:
Ver original
  1. function extraer($cadena){
  2.     $patron = '/^.*\s(\d+)\s.*$/is';
  3.     return array_sum(array_map(function($parte) use ($patron){
  4.         return preg_replace($patron, '$1', $parte);
  5.     }, preg_split('/\n/', $cadena)));
  6. }
  7.  
  8. echo 'Ganaste ' . extraer('03:51 You gained 1 experience points.
  9. 03:51 You gained 100 experience points.
  10. 03:51 You gained 1000 experience points.') . ' puntos.';

Lo anterior imprimirá: "Ganaste 1101 puntos".

Esto funciona así. A la función le paso como parámetro el texto completo, con todas sus líneas y saltos de línea. En la función, creo la expresión regular para hacer la búsqueda, el cual consiste en que, la cadena a buscar, tenga a cualquier caracter al inicio, de cero a más, seguido de un espacio, uno o más números, otro espacio y cualquier caracter hasta el final, de cero a más. La búsqueda será global (la s) y sin hacer distinciones entre mayúsculas y minúsculas (la i).

Luego, con la función array_map, aplico una llamada de retorno al array generado por la función preg_split, con la cual he generado un array integrado por cada línea del texto recibido, la cual ha sido separada a partir de los saltos de línea. En la llamada de retorno, la cual usa la expresión regular creada previamente, devuelve una cadena, producto de aplicar la función preg_replace a la línea que actualmente se está analizando en la llamada de retorno. Dicha función verificará si el contenido de la línea coincide con la expresión regular y, de ser así, la sustituirá por el primer (y único) grupo anónimo en la expresión regular, denotado por lo que está contenido entre paréntesis. Este valor es retornado por la llamada de retorno y se pasa a analizar la siguiente línea. La función array_map, genera un nuevo array con cada dato devuelto por la llamada de retorno, además de actuar como una estructura repetitiva, por lo que, al final del análisis del texto, se generará un array con los valores numéricos buscados y, con la función array_sum, sumo a todos estos valores, resultado que es devuelto por la función principal.

Cabe señalar que, si tu versión de PHP es inferior a la 5.3.0, no podrás utilizar una función lambda como llamada de retorno y, en su lugar, deberás de crear una función aparte que realizará el mismo proceso y solo tendrías que colocar su nombre como el primer argumento de la función.

Código PHP:
Ver original
  1. function ejemplo($parametro){
  2.     //...
  3. }
  4. array_map('ejemplo', $array);

Y lo mismo va por el uso del operador use, debiendo hacer global al parámetro o creándolo en la misma función. Esta forma te servirá en una versión anterior a PHP 5.3.0:

Código PHP:
Ver original
  1. function foo($parte){
  2.     $patron = '/^.*\s(\d+)\s.*$/is';
  3.     return preg_replace($patron, '$1', $parte);
  4. }
  5.  
  6. function extraer($cadena){
  7.     return array_sum(array_map('foo', preg_split('/\n/', $cadena)));
  8. }
  9.  
  10. echo 'Ganaste ' . extraer('03:51 You gained 1 experience points.
  11. 03:51 You gained 100 experience points.
  12. 03:51 You gained 1000 experience points.') . ' puntos.';

También podrías usar directamente a la expresión regular, sin asignarla a una variable, así evitas el problema de la compatibilidad por el uso del operador use.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand