Tengo una matriz de objetos con un conjunto de ciertas palabras como entidades. Por ejemplo :
footnotes: [ { sourceText: 'red'}, { sourceText: 'green'}, { sourceText: 'yellow'}, { sourceText: 'purple'}, { sourceText: 'gray'}, { sourceText: 'blue'} ]Y tengo algunas oraciones al azar. Por ejemplo: 'Conduzco un coche rojo entre campos verdes y miro el cielo gris'
El objetivo es marcar las palabras con asteriscos según el objeto de las entidades:
'Conduzco un auto rojo* entre campos verdes** y miro el cielo gris***'
Estoy tratando de hacer esto en un bucle con silce y Regexp pero no puedo concatenar la cadena correctamente
¿Cómo se puede hacer esto?
Aquí está mi código
footnotes = [{ sourceText: "red", solve: false }, { sourceText: "green", solve: false }, { sourceText: 'yellow', solve: false }, { sourceText: "purple", solve: false }, { sourceText: "grey", solve: false }, { sourceText: "blue", solve: false } ] starGenerate = function(count) { let result = '' for (let i = 0; i < count; i++) { result += '*' } return result }, let post = { id: 21321, data: {}, lead: 'I drive a red car among green fields and look at the gray sky' } post.check = function() { let str, concat = '' let self = this; let starcounter = 0 for (let i = 0; i < self.entities.length; i++) { let reg = new RegExp(`${self.entities[i].sourceText}`); if (match = reg.exec(self.lead) && self.entities[i].solve === false) { concat = self.lead.replace(reg, `${self.entities[i].sourceText + starGenerate(++starcounter)}`) self.entities[i].solve = true } } } post.entities = footnotesPuede hacer esto con una expresión regular (usando | ), y luego usar el argumento de devolución de llamada de replace para insertar los asteriscos. Prepararía el texto de reemplazo para cada palabra y lo colocaría en un objeto tecleado por palabra. Su función starGenerate no es realmente necesaria, ya que existe el método de repeat .
function putAsterisks(footnotes, sentence) { let alternatives = footnotes.map(({sourceText}) => sourceText).join("|"); let replacements = Object.fromEntries(footnotes.map(({sourceText}, i) => [sourceText, sourceText + "*".repeat(i + 1)] )); let regex = RegExp("\\b(" + alternatives + ")\\b", "gi"); return sentence.replace(regex, m => replacements[m]); } // Example: let footnotes = [{ sourceText: 'red'}, { sourceText: 'green'}, { sourceText: 'yellow'}, { sourceText: 'purple'}, { sourceText: 'gray'}, { sourceText: 'blue'}]; let sentence = 'I drive a red car among green fields and look at the gray sky with a red moon'; console.log(putAsterisks(footnotes, sentence));Esto supone que los textos de origen no contienen caracteres que tengan un significado especial en las expresiones regulares. Si esto pudiera suceder, entonces use esta respuesta para escapar primero de esas palabras.
Puede hacer lo mismo sin expresiones regulares dividiendo su cadena y usando el map entre todas las palabras. Esto funciona bien siempre que no haya más puntuación en su cadena de entrada
const footnotes=[{sourceText:"red",solve:!1},{sourceText:"green",solve:!1},{sourceText:"yellow",solve:!1},{sourceText:"purple",solve:!1},{sourceText:"grey",solve:!1},{sourceText:"blue",solve:!1}]; const input = 'I drive a red car among green fields and look at the grey sky' const footnotesIndex = footnotes.reduce( (acc,i) => (acc[i.sourceText] = i.solve,acc),{}); let star=1 const result = input.split(" ").map( word =>footnotesIndex[word] != undefined ? word + "*".repeat(star++) : word).join(" "); console.log(result);