Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Función para extraer y usar texto de un string

Estas en el tema de Función para extraer y usar texto de un string en el foro de PHP en Foros del Web. Hola comunidad, tengo una duda... Estoy creando un sistema que busque en una cadena de texto 'algo' para luego procesarlo. En mi caso ese 'algo' ...
  #1 (permalink)  
Antiguo 10/10/2014, 03:47
 
Fecha de Ingreso: abril-2014
Ubicación: 3 metros sobre la casa de abajo
Mensajes: 40
Antigüedad: 10 años
Puntos: 6
Función para extraer y usar texto de un string

Hola comunidad, tengo una duda...

Estoy creando un sistema que busque en una cadena de texto 'algo' para luego procesarlo. En mi caso ese 'algo' es un número (el de color azúl):

03:51 You gained 1 experience points.
03:51 You gained 100 experience points.
03:51 You gained 1000 experience points.

Lo que necesito es sacar de la cadena el número mostrado (de color azul) de una serie de cadenas como las mostradas arriba (idénticas, salvo por el número azul y la longitud de este) y sumar esos valores para mostrarlos aparte en una especie de "reporte".

Ejemplo:

Texto ingresado:

Cita:
03:51 You gained 1 experience points.
03:51 You gained 100 experience points.
03:51 You gained 1000 experience points.
Resultado:

Cita:
Ganaste en total 1100 puntos de exp.
(1100 es el equivalente a la suma de los números tomados de la cadena: 1 + 100 + 1000)
Si alguien me puede aclarar la situación sería de gran ayuda para mí, ya que a partir de eso podría hacer otras cosas "parecidas" a lo que necesito en este momento.

De antemano muchas gracias a quien pueda guiarme, estaré enormemente agradecido. Saludos desde Venezuela.
__________________
Vivir y aprender... ojalá pudiera resistir por lo menos 150 años.
  #2 (permalink)  
Antiguo 10/10/2014, 04:33
Avatar de garciasanchezdani  
Fecha de Ingreso: noviembre-2011
Mensajes: 429
Antigüedad: 12 años, 5 meses
Puntos: 51
Respuesta: Función para extraer y usar texto de un string

Hola @Luminis :)
Este código puede servirte:

Código PHP:
Ver original
  1. $str1 = 'gained 1 point';
  2. preg_match_all('!\d+!', $str1, $matches);
  3. $number1 = implode(' ', $matches[0]);
  4.  
  5. $str2 = 'gained 100 points';
  6. preg_match_all('!\d+!', $str2, $matches);
  7. $number2 = implode(' ', $matches[0]);
  8.  
  9. $str3 = 'gained 1000 points';
  10. preg_match_all('!\d+!', $str3, $matches);
  11. $number3 = implode(' ', $matches[0]);
  12.  
  13. echo $number1 + $number2 + $number3;

Saludos!
__________________
Diseño Web Jaén
  #3 (permalink)  
Antiguo 10/10/2014, 14:22
 
Fecha de Ingreso: abril-2014
Ubicación: 3 metros sobre la casa de abajo
Mensajes: 40
Antigüedad: 10 años
Puntos: 6
Respuesta: Función para extraer y usar texto de un string

Hola @garciasanchezdani gracias por tu solución, el problema es que debo usar una cantidad indeterminada de texto que será procesado, como por ejemplo este:

03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 22 hitpoints due to your attack.
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: a cherry
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: 3 gold coins
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: nothing
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: 5 gold coins
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: nothing
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: nothing
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: 3 gold coins
03:51 A bug loses 7 hitpoints due to your attack.
03:51 You gained 27 experience points.
03:51 Loot of a bug: a cherry, a gold coin

(Y este se queda corto, ya ue debo procesar mucho más de 1000 líneas)

Así tal cual debo pegar los "serverlogs" para procesarlos. Sin embargo, revisaré la funcióm preg_match_all, trateré de ahondar mas en ella y ver que saco de ahi ;)

Gracias por tu ayuda :)
__________________
Vivir y aprender... ojalá pudiera resistir por lo menos 150 años.
  #4 (permalink)  
Antiguo 10/10/2014, 15:42
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
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
  #5 (permalink)  
Antiguo 10/10/2014, 15:46
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Función para extraer y usar texto de un string

La forma mas fácil y rápida es esta:
Código PHP:
Ver original
  1. $cadena = "03:51 You gained 1 experience points.";
  2. $numero = filter_var(substr($cadena, 5), FILTER_SANITIZE_NUMBER_INT);
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #6 (permalink)  
Antiguo 12/10/2014, 02:29
 
Fecha de Ingreso: abril-2014
Ubicación: 3 metros sobre la casa de abajo
Mensajes: 40
Antigüedad: 10 años
Puntos: 6
Respuesta: Función para extraer y usar texto de un string

Gracias a todos por sus respuestas y posibles soluciones, la verdad es que de cada una saqué algo y al final obtuve lo que quería. Hice lo siguiente:

Cita:
String de entrada:
03:51 You gained 1 experience points.
03:51 You gained 100 experience points.
03:51 You gained 1000 experience points.
(más otras cientos e incluso miles de lineas similares)
Como debo obtener los valores 1, 100, 1000, hice lo siguiente:

Mediante una expresión regular eliminé la hora (03:51), ya que el texto que debo procesar contiene la hora del sistema y en cada linea esta me aparece, por lo tanto, usar filter_var me daba como resultado los valores:

Cita:
03511035110003511000
Es decir, los números de cada línea, incluyendo la hora, con lo cual al momento de querer sumar los valores del centro de cada línea me aparecían los valores de la hora y obviamente estaba malo (al menos para lo que yo necesito).

Entonces...

Por medio de una expresion regular borré del string los siguiente:

Cita:
'/[0-9][0-9]:[0-9][0-9] /'
Dejando solamente al ser procesado, esto:

Cita:
You gained 1 experience points.
You gained 100 experience points.
You gained 1000 experience points.
Entonces aquí es donde entra: filter_var, dejando exclusivamente:

Cita:
1
100
1000

Que luego serán procesados.
El objetivo era sacar de alguna manera los números del "medio" de cada línea, y a pesar de que posiblemente esta no sea la manera más sutil de conseguirlo, para lo que necesito hacer es sencillamente viable, ya que me limpia las demás líneas que son MUY diferentes a las que usé para este ejemplo y que también deberán ser procesadas.

Un fuerte abrazo para cada uno de ustedes, y muchísimas gracias por su valiosa ayuda, cada uno supo hacerme entender algo para lograr mi objetivo con este código, que a pesar de ser sencillo para muchos, para mí es dificil porque estoy aprendiendo y la ayuda que ustedes me hicieron llegar fue más que valiosa.

Saludos y un abrazo desde Venezuela.
__________________
Vivir y aprender... ojalá pudiera resistir por lo menos 150 años.

Etiquetas: string, usar
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:42.