Reemplazar palabras individuales que contienen un punto decimal - Función Regx php

Iniciado por OssoH, 25 Noviembre 2021, 11:34 AM

0 Miembros y 1 Visitante están viendo este tema.

OssoH

Hola,
estoy usando expresiones regulares para buscar palabras individuales y las reemplazar por otra.

Tengo esta función que funciona bien siempre y cuando la palabra que queramos reemplazar no tengo un punto decimal al final.


// Busca una palabra completa y la sustituye por otra
// insensible minusculas y mayúsculas
// https://stackoverflow.com/questions/19317493/php-preg-replace-case-insensitive-match-with-case-sensitive-replacement
function preg_ireplace($data, $search, $replace) {
$data = preg_replace_callback('/\b'.$search.'\b/i', function($matches) use ($replace)
{
   $i=0;
   return join('', array_map(function($char) use ($matches, &$i)
   {
      //return ctype_lower($matches[0][$i++])?strtolower($char):strtoupper($char);
      return $char;
   }, str_split($replace)));
}, $data);
return $data;
}



mi código es

$cadena = 'p.e. castellano g. marig ab pul. 1a';
$text = Tools::preg_ireplace($cadena, 'P.E.', 'HOLA');
$text = Tools::preg_ireplace($cadena, 'casteLLano', '***');
echo '<br>'.$cadena;
echo '<br>'.$text;


El resultado :
p.e. castellano g. marig ab pul. 1a
p.e. *** g. marig ab pul. 1a

Quiero que la palabra P.E. la interprete como palabra individual y no lo hace.
¿Alguien se le ocurre como hago que acepte el punto decimal?
Muchas gracias




OssoH

De momento lo estoy haciendo de forma "cutre"

1.- Reemplazo el . por X
2-- llamar a la función preg_ireplace
3.- Lo vuelvo a reemplazar esta vez la X por el .

$cadena = str_ireplace(".", "X", $cadena);

EdePC

1. Recuerda que le estás pasando una expresión regular como texto, entonces lo correcto sería pasarle P\.E\. para escapar los puntos, sino va a coincidir con palabras como pies

2. El segundo \b te dará problemas porque si haces coincidir p.e. te darás cuenta que ya deja de ser una palabra por culpa del punto, así que no habrá coincidencia ya que el siguiente caracter es un Espacio, lo esperado sería que sea un caracter alfanumérico

\b solo hace coincidir cuando hay caracter_alfa|no_caracter_alfa o no_caracter_alfa|caracter_alfa, en tu caso tendrías no_caracter_alfa|no_caracter_alfa

Como lo que estás buscando son "palabras" que contienen caracteres especiales (puntos) pues puedes quitar ese último \b o usar otro separador que te convenga, por ejemplo un espacio, se me ocurre algo como '/\b'.$search.'(?= )/i'

OssoH

Muchas gracias.
He hecho varias pruebas y he encontrado un caso donde no funciona

Tengo esto :

$cadena = 'p.e. castellano g. marig ab pul. 1a';
$text = Tools::preg_ireplace($cadena, '1a', '1A');

Como resultado me deberia dar :
p.e. castellano g. marig ab pul. 1A
y me da el siguiente :
p.e. castellano g. marig ab pul. 1a

La palabra "1a" no me la encuentra.


function preg_ireplace($data, $search, $replace) {
// \b => busca palabras completas
// $data = preg_replace_callback('/\b'.$search.'\b/i', function($matches) use ($replace)
$data = preg_replace_callback('/\b'.$search.'(?= )/i', function($matches) use ($replace)
{
   $i=0;
   return join('', array_map(function($char) use ($matches, &$i)
   {
      // return ctype_lower($matches[0][$i++])?strtolower($char):strtoupper($char);
      return $char;
   }, str_split($replace)));
}, $data);
return $data;
}


OssoH

He cambiado la expresión regular por la siguiente y parece que funciona pero al no tener mucha idea de expresiones regulares no se si estoy poniendo una burrada.

'/\b'.$search.'(?=[\s]|$)/i'

¿Que opinan?

Danielㅤ

Hola, yo personalmente no usaría expresiones regulares, en todos los proyectos que he realizado nunca he usado regex, todo lo he logrado hacer con funciones/métodos.

Lo que vos estás buscando es una operación fácil de hacer y aunque si se puede lograr con regex, pero el uso de expresiones regulares es para operaciones más o mucho más complejas.

Lo que yo haría en tu caso es lo siguiente:

1). Dividir la cadena por espacios usando la función split().

2). Como ahora tengo un array() con los elementos de la cadena que serían las palabras, voy a necesitar una función que encuentre un texto exacto dentro del array y lo reemplace por otro, es decir que buscaría un elemento que tenga X valor idéntico al que busco y lo reemplace por otro.

3). Ahora uso la función join() para volver convertir a string la cadena de texto y la guardo en una variable.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!

OssoH

Cita de: Danielㅤ en 29 Noviembre 2021, 15:04 PM
Hola, yo personalmente no usaría expresiones regulares, en todos los proyectos que he realizado nunca he usado regex, todo lo he logrado hacer con funciones/métodos.

Lo que vos estás buscando es una operación fácil de hacer y aunque si se puede lograr con regex, pero el uso de expresiones regulares es para operaciones más o mucho más complejas.

Lo que yo haría en tu caso es lo siguiente:

1). Dividir la cadena por espacios usando la función split().

2). Como ahora tengo un array() con los elementos de la cadena que serían las palabras, voy a necesitar una función que encuentre un texto exacto dentro del array y lo reemplace por otro, es decir que buscaría un elemento que tenga X valor idéntico al que busco y lo reemplace por otro.

3). Ahora uso la función join() para volver convertir a string la cadena de texto y la guardo en una variable.


Saludos

Lo pensé y era la última alternativa en el caso de no sacar la expresión regular.
Parece ser por el momento que la expresión regular me funciona
Gracias