¿Hay alguna manera de usar expresiones regulares para averiguar cuántas veces puede aparecer una palabra en una cadena determinada a pesar del orden de sus caracteres? Tomemos "NEOTWONE" como nuestros ejemplos, que deberían devolver un recuento de "4"
NEO --> 'ONE' --> +1 OTW --> 'TWO' --> +1 TWO --> 'TWO' --> +1 ONE --> 'ONE' --> +1Esto es lo que tengo hasta ahora y no pude hacer que la expresión regular funcione correctamente.
const nums = ['ZERO','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']; function amount(str,count=0) { for (const n of nums) { RegExp(`\\b[${str}]+\\b`,'g').test(n) && count++; } return count; } console.log(amount('ONE')); // 1 console.log(amount('ONEOTW')); // 2 console.log(amount('ONENO')); // 1 console.log(amount('NEOTWONE')); // 2Como puede ver, los ejemplos 2, 3 y 4 anteriores no generaron el resultado correcto, que debería ser:
console.log(amount('ONEOTW')); // 3 console.log(amount('ONENO')); // 2 console.log(amount('NEOTWONE')); // 4Soy nuevo en expresiones regulares, cualquier comentario será muy apreciado con una explicación. Millones de gracias de antemano :)
Tendrás que crear una gran expresión regular para eso:
Primero, cree todas las permutaciones únicas de todas las cadenas de entrada ( nums ).
Concatene estos en una expresión regular, usando | como separador, pero use la anticipación, de modo que un carácter pueda ser parte de una coincidencia varias veces. Entonces, por ejemplo, para "UNO", la expresión regular sería:
(?=ONE|OEN|ENO|EON|NEO|NOE)Pero entonces también incluirías todas las permutaciones de "ZERO" y todas las demás palabras.
function* permutations(word) { if (word.length <= 1) return yield word; for (let i = 0; i < word.length; i++) { for (let perm of permutations(word.slice(0, i) + word.slice(i + 1))) { yield word[i] + perm; } } } function createRegex(words) { const allPermutations = words.flatMap(word => [...new Set(permutations(word))]); return RegExp("(?=" + allPermutations.join("|") + ")", "g"); } function countMatches(regex, phrase) { return phrase.match(regex)?.length ?? 0; } const nums = ['ZERO','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']; const regex = createRegex(nums); for (const test of ['ONE', 'ONEOTW', 'ONENO', 'NEOTWONE']) { console.log(test, countMatches(regex, test)); }Tenga en cuenta que para la segunda prueba, la respuesta es 3, no 2, ya que "NEO" también cuenta.