Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] comparacion de cadenas

Estas en el tema de comparacion de cadenas en el foro de PHP en Foros del Web. Hola, He reducido un escenario que tengo a esto: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código PHP: Ver original $x = [ //pajar     "A,B,C,D" ,     ...
  #1 (permalink)  
Antiguo 22/01/2016, 08:43
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 11 años, 6 meses
Puntos: 10
comparacion de cadenas

Hola,

He reducido un escenario que tengo a esto:

Código PHP:
Ver original
  1. $x = [ //pajar
  2.     "A,B,C,D",
  3.     ".A,B,C,D",
  4.     "A,B.C,D"
  5. ];
  6.  
  7. $y = [//aguja
  8.     "A,B", //necesito true para $x[0] y $x[2]  ... y false para $[x1]
  9.     ".A,B", //necesito true para $[x1] y false para las otras dos
  10.     "B,C,D", // necesito true para $x[0] y $x[1] ... y false para $[x2]
  11.     "B.C,D" // necesito true para $x[2] y false para las otras dos
  12. ];

Antes lo tenia fácil siempre con separador una coma "," y lo resolvía con :
Código PHP:
Ver original
  1. foreach($x as $pajar){
  2.     foreach($y as $aguja){
  3.         if(strpos($pajar,$aguja) !== false){
  4.             echo "true";
  5.         }else{
  6.             echo "false";
  7.         }
  8.     }
  9. }


... pero por necesidad tengo que poner para algunos caracteres un prefijo punto "." y excepto al principio (que se queda como prefijo ) , el mismo punto hace de separador.

lo que me da confusiones en la manera que lo hacia antes

¿Alguien me puede dar alguna idea como resolverlo ?

Gracias
  #2 (permalink)  
Antiguo 22/01/2016, 14:14
Avatar de carlillos  
Fecha de Ingreso: febrero-2007
Ubicación: México
Mensajes: 245
Antigüedad: 17 años, 9 meses
Puntos: 21
Respuesta: comparacion de cadenas

Para comparaciones más complejas podrías utilizar expresiones regulares.
Código PHP:
Ver original
  1. $x = array(//pajar
  2.     "A,B,C,D",
  3.     ".A,B,C,D",
  4.     "A,B.C,D"
  5. );
  6.  
  7. $y = array(//aguja
  8.     "^A,B", //símbolo "^" para que sólo sea true si "A,B" aparece al inicio de la cadena
  9.     "\.A,B", //símbolo "\" para escapar "." y lo tome literalmente
  10.     "B,C,D",
  11.     "B\.C,D" //símbolo "\" para escapar "." y lo tome literalmente
  12. );
  13.  
  14. foreach($x as $pajar){
  15.     foreach($y as $aguja){
  16.         if(preg_match("/$aguja/", $pajar)){
  17.             echo "true";
  18.         }else{
  19.             echo "false";
  20.         }
  21.     }
  22. }
El código que puse sirve para este caso en específico, tendrías que modificar la expresión regular para adaptarla a tu uso.
  #3 (permalink)  
Antiguo 22/01/2016, 18:45
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 11 años, 6 meses
Puntos: 10
Respuesta: comparacion de cadenas

Muchas gracias por responder dándome muy buena pista.

Lo que pasa es que los regexp no los domino tanto asi que he construido un algoritmo en php que me resuelve la cosa ... incluso lo he complicado mas

Seguro que con expresiones regulares queda mucho mas elegante pero solo se un poquito basico de ellas.

Aqui va mi solucion ( mas primitiva creo ... pero funciona )

Código PHP:
Ver original
  1. $x = array(//pajar
  2.     "A,B,C,D",
  3.     ".A,B,C,D",
  4.     ".A.B,C,D",
  5.     ".A,B.C,D",
  6.     ".A,B,C.D",
  7.     "A.B,C,D",
  8.     ".A.B.C,D",
  9.     ".A.B.C.D"
  10. );
  11.  
  12. $y = array(//aguja
  13.     "A,B",
  14.     ".A,B",
  15.     "B,C",
  16.     "B.C",
  17.     "C,D",
  18.     ".C,D",
  19.     "A,B,C",
  20.     ".A,B,C",
  21.     "A,B.C",
  22.     "B,C,D",
  23.     "B.C,D"
  24. );
  25.  
  26. foreach($x as $pajar){
  27.     foreach($y as $aguja){
  28.         //Busca primero la posicion de aguja en el pajar
  29.         $posicion = strpos($pajar,$aguja);
  30.         // si la coincidencia esta al principio, aunque tenga punto delante o no, siempre sera true
  31.         if($posicion === 0){
  32.             echo $aguja." true ".$pajar."<br>";
  33.         //si hay coincidencia pero no al principio
  34.         }elseif($posicion !== false){
  35.             //si la aguja tiene un punto (donde sea ) siempre sera true
  36.             if(strpos($aguja,".") !== false){
  37.                 echo $aguja." true ".$pajar."<br>";
  38.             //si aguja no tiene punto
  39.             }else{
  40.                 //si el caracter delante de la posicion de la coincidencia es punto,
  41.                 //siempre sera false puesto que la aguja no tiene punto
  42.                 if($pajar[$posicion - 1] === "."){
  43.                     echo $aguja." false ".$pajar."<br>";
  44.                 }
  45.             }
  46.         //por logica si no hai coincidencia siempre sera false
  47.         }else{
  48.             echo $aguja." false ".$pajar."<br>";
  49.         }
  50.     }
  51. }

Si alguien tiene tiempo de traducirla en expresiones regulares estaría curioso como saldria

Gracias
  #4 (permalink)  
Antiguo 22/01/2016, 19:16
Avatar de carlillos  
Fecha de Ingreso: febrero-2007
Ubicación: México
Mensajes: 245
Antigüedad: 17 años, 9 meses
Puntos: 21
Respuesta: comparacion de cadenas

Esta vez no pusiste los resultados que esperas así que traté de adivinarlos.

Código PHP:
Ver original
  1. $x = array(//pajar
  2.     "A,B,C,D",
  3.     ".A,B,C,D",
  4.     ".A.B,C,D",
  5.     ".A,B.C,D",
  6.     ".A,B,C.D",
  7.     "A.B,C,D",
  8.     ".A.B.C,D",
  9.     ".A.B.C.D"
  10. );
  11.  
  12. $y = array(//aguja
  13.     "^A,B",
  14.     "\.A,B",
  15.     "B,C",
  16.     "B\.C",
  17.     ",C,D",
  18.     "\.C,D",
  19.     "^A,B,C",
  20.     "\.A,B,C",
  21.     "A,B\.C",
  22.     ",B,C,D",
  23.     "B\.C,D"
  24. );
  25.  
  26. foreach($x as $pajar){
  27.     foreach($y as $aguja){
  28.         if(preg_match("/$aguja/", $pajar)){
  29.             echo "true";
  30.         }else{
  31.             echo "false";
  32.         }
  33.     }
  34. }
  #5 (permalink)  
Antiguo 22/01/2016, 19:32
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 11 años, 6 meses
Puntos: 10
Respuesta: comparacion de cadenas

Je je ... gracias amigo lo he intentado pero fíjate que para buscar

"B,C" en -> ".A.B,C,D" sale true y debería ser false

y hay otros mas en principio busco todas las combinaciones

Tenga en cuenta que tambien puedo tener variaciones ( el primer ejemplo que puse era para simplificar )
seria posible tambien B,A,C,D -> C,B,D,A etc etc ... incluso longitudes diferentes E,G,P,O,H,Q,N,P,W etc y para las agujas tambien ... con puntos tambien y variaciones de ellos


La idea tuya me gusto mucho pero no se adapta si las $agujas que no llevan punto delante no están al principio del pajar

Claro ... me dijiste que solo funciona para el ejemplo que te di al principio ... entonces a partir de tu idea he intentado ( incluso poner automáticamente los símbolos "\" y "^" ) porque los datos de $agujas vienen de una base de datos ... pero no encuentro solución para el ejemplo que puse aquí al principio en este mensaje

En principio las $agujas que llevan punto dentro no dan problemas pero las que no tienen si porque si la coincidencia no esta al principio, no sabe cual es el caracter delante de esta coincidencia si es coma o punto.



Pero si encuentras alguna manera de hacer esto te lo agradezco

Gracias de todos modos ...

Última edición por matake; 22/01/2016 a las 19:44
  #6 (permalink)  
Antiguo 22/01/2016, 20:24
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 11 años, 6 meses
Puntos: 10
Respuesta: comparacion de cadenas

Pues al final ... he adaptado tu idea ( que me gustaba mas desde el principio ) y creo que se adapta a todas las combinaciones ( tampoco voy a tener combinaciones mas grandes de 10 - 20 characteres ( excluidos puntos y comas )

aqui va

Código PHP:
Ver original
  1. $x = array(//pajar
  2.     "A,B,C,D",
  3.     ".A,B,C,D",
  4.     ".A.B,C,D",
  5.     ".A,B.C,D",
  6.     ".A,B,C.D",
  7.     "A.B,C,D",
  8.     ".A.B.C,D",
  9.     ".A.B.C.D"
  10. );
  11.  
  12. $y = array(//aguja
  13.     "A,B",
  14.     ".A,B",
  15.     "B,C",
  16.     "B.C",
  17.     "C,D",
  18.     ".C,D",
  19.     "A,B,C",
  20.     ".A,B,C",
  21.     "A,B.C",
  22.     "B,C,D",
  23.     "B.C,D"
  24. );
  25.  
  26.  
  27. foreach($x as $pajar){
  28.     foreach($y as $aguja){
  29.    
  30.         //si aguja no empieza por punto
  31.         if($aguja[0] !== "."){
  32.             //si se encuentra al principio
  33.             if(strpos($pajar,$aguja) === 0 ){
  34.                 $simbolo = "^";
  35.             //si no esta al principio
  36.             }else{
  37.                 $simbolo = ",";
  38.             }
  39.         }else{
  40.             //para los puntos se reemplazan todas con "\" mas abajo
  41.             $simbolo = "";
  42.         }
  43.         //luego añadir "\" para todas que llevan punto
  44.         $aguja = str_replace(".","\\.",$aguja);
  45.        
  46.         //añadir el simbolo al regexp
  47.         if(preg_match("/$simbolo$aguja/", $pajar)){
  48.             echo $aguja." true ".$pajar."<br>";
  49.         }else{
  50.             echo $aguja." false ".$pajar."<br>";
  51.         }
  52.     }
  53. }

Gracias otra vez y saludos
  #7 (permalink)  
Antiguo 22/01/2016, 20:43
Avatar de carlillos  
Fecha de Ingreso: febrero-2007
Ubicación: México
Mensajes: 245
Antigüedad: 17 años, 9 meses
Puntos: 21
Respuesta: comparacion de cadenas

Cita:
"B,C" en -> ".A.B,C,D" sale true y debería ser false
Esta expresión es más flexible para que la puedas adaptar a otros casos:
Código PHP:
Ver original
  1. "^B,C|[^.]B,C"
Se ve compleja pero no lo es tanto si la divides por partes, el símbolo "|" divide la expresión en dos y va a devolver true si alguna de las dos el válida, primera parte:

"^B,C" es válida si "B,C" está exactamente al inicio de la cadena.

"[^.]B,C" en este caso cambia el significado de "^" cuando está dentro de "[]" significa que sólo sea válida si el símbolo que le sigue no está presente, en español:
Busca cualquier caracter que no sea un "." antes de "B,C".

Por lo tanto esa expresión te devolvería false para ".A.B,C,D", true para ".A,B,C,D", false para ".B,C,D,A", true para "B,C,D,A".
  #8 (permalink)  
Antiguo 22/01/2016, 21:32
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 11 años, 6 meses
Puntos: 10
Respuesta: comparacion de cadenas


Falta poco y llegamos a E=MC²

entonces seria esto
Código PHP:
Ver original
  1. foreach($x as $pajar){
  2.     foreach($y as $aguja){
  3.    
  4.         //si no hay punto al principio de $aguja
  5.         if($aguja[0] !== "."){
  6.             $regexp = "^$aguja|[^.]$aguja";
  7.         }
  8.         //si la aguja tiene puntos (donde sea )
  9.         if(strpos($aguja,".") !== false ){
  10.             //añadir "\" para todas que llevan punto
  11.             $aguja = str_replace(".","\\.",$aguja);
  12.             $regexp = $aguja;
  13.         }
  14.        
  15.    
  16.         //añadir el simbolo al regexp
  17.         if(preg_match("/$regexp/", $pajar)){
  18.             echo $aguja." true ".$pajar."<br>";
  19.         }else{
  20.             echo $aguja." false ".$pajar."<br>";
  21.         }
  22.     }
  23. }

Etiquetas: cadenas, comparacion
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 15:37.