Tengo la expresión regular:
const regex = /^\d*\.?\d{0,2}$/y su inversa (creo) de
const inverse = /^(?!\d*\.?\d{0,2}$)/ La primera expresión regular valida que la cadena se ajuste a cualquier número positivo, lo que permite un decimal y dos dígitos decimales (p. ej., 150 , 14. , 7.4 , 12.68 ). La segunda expresión regular es la inversa de la primera, y al hacer algunas pruebas, estoy bastante seguro de que está dando el resultado esperado, ya que solo valida cuando la cadena es cualquier cosa menos un número que puede tener un decimal y dos dígitos después (por ejemplo, 12..05 , a5 , 54.357 ).
Mi objetivo es eliminar cualquier carácter de la cadena que no se ajuste a la primera expresión regular. Pensé que podría hacerlo de esta manera:
let myString = '123M.45'; let fixed = myString.replace(inverse, '');Pero esto no funciona como se esperaba. Para depurar, intenté cambiar el carácter de reemplazo a algo que pudiera ver:
let fixed = myString.replace(inverse, 'ZZZ'); Cuando hago esto, fixed se convierte en: ZZZ123M.45
Cualquier ayuda sería muy apreciada.
Creo que entiendo su lógica aquí tratando de encontrar una expresión regular que sea la inversa de la expresión regular que coincida con su cadena válida, con la esperanza de que le permita eliminar cualquier carácter que haga que su cadena no sea válida y deje solo la cadena válida. Sin embargo, no creo que replace() le permita resolver su problema de esta manera. De los documentos de MDN :
El método replace() devuelve una nueva cadena con algunas o todas las coincidencias de un patrón reemplazadas por un reemplazo.
En su patrón inverse , está utilizando una anticipación negativa. Si tomamos un ejemplo simple de X(?!Y) podemos pensar en esto como "coincidir con X si no va seguido de Y". En tu patrón, tu "X" es ^ y tu "Y" es \d*\.?\d{0,2}$ . Según tengo entendido, la razón por la que está obteniendo ZZZ123M.45 es que está encontrando el primer ^ (es decir, el comienzo de la cadena) que no está seguido por su patrón \d*\.?\d{0,2}$ , y dado que 123M.45 no coincide con su patrón "Y", su búsqueda anticipada negativa se satisface y el comienzo de su cadena se compara y "reemplaza" con ZZZ.
Eso (creo) es una explicación de lo que estás viendo.
Propondría una solución alternativa a su problema que se ajuste mejor a mi forma de entender el método .replace() . En lugar de tu patrón inverse , prueba este:
const invalidChars = /[^\d\.]|\.(?=\.)|(?<=\.\d\d)\d*/g const myString = '123M..456444'; const fixed = myString.replace(invalidChars, '');Aquí estoy usando un patrón que creo que coincidirá con los caracteres individuales que desea eliminar. Vamos a desglosar lo que está haciendo este:
[^\d\.] : coincide con caracteres que no son dígitos
\.(?=\.) : partido . carácter si va seguido de otro . personaje.
(?<=\.\d\d)\d* : coincidencia de dígitos precedidos por un decimal y 2 dígitos
Luego, uno todos estos con OR ( | ) para que coincida con cualquiera de los patrones anteriores, y uso la bandera g para que reemplace todas las coincidencias, no solo la primera.
No estoy seguro de si esto cubrirá todos sus casos de uso, pero pensé en intentarlo. Aquí hay un enlace a un desglose que podría ser más útil que el mío, y puede usar esta herramienta para modificar el patrón si es necesario.
no creo que puedas hacer esto
elimine cualquier carácter de la cadena que no se ajuste a la primera expresión regular
Porque la coincidencia de expresiones regulares está pensada para toda la cadena, y replace se usa para reemplazar solo una PARTE dentro de esa cadena. Por lo tanto, Regex inside replace debe ser Regex para coincidir solo con caracteres no deseados, no Regex invertido.
Lo que podría hacer es validar la cadena con su regex original, luego, si no es válida, reemplace y valide nuevamente.
//if (notValid), replace unwanted character // replace everything that's not a dot or digit const replaceRegex = /[^\d.]/g; // notice g flag here to match every occurrence const myString = '123M.45'; const fixed = myString.replace(replaceRegex, ''); console.log(fixed) // validate again