reactjs - Extraer/Encontrar palabras específicas de un párrafo en JavaScript
Actualmente estoy trabajando en un proyecto de React Native (basado en JS) en el que necesito coincidir y extraer los nombres de los hospitales de párrafos dinámicos que provienen del servidor backend. Sé sobre match(), includes(), etc., pero estos no funcionan en este caso ya que los nombres son dinámicos y pueden contener varias palabras.
¡Alguna sugerencia!
Respuesta #1
Puedes resaltar las palabras al mostrar el texto HTML.
Una expresión regular se puede crear a partir de una lista de palabras mediante:
const regex = new RegExp(`\\b(${words.map(word => `(${word})`).join('|')})\\b`, 'gi');
El HTML sin procesar se puede establecer usando la propiedad dangerouslySetInnerHTML del <p>.
const highlightWords = ['beef', 'ham', 'pork', 'sausage', 'ribeye', 'ribs'];
class WordHighlighter extends React.Component {
constructor(props) {
super(props);
this.state = { regex: this._updateRegex(this.props.highlightWords), paragraphs: [] };
};
/* @private */ _updateRegex(words) {
return new RegExp(`\\b(${words.map(word => `(${word})`).join('|')})\\b`, 'gi');
}
/* @private */ _highlightWords(paragraph) {
return paragraph.replace(this.state.regex, `<span class="highlight">$1</span>`);
}
componentDidMount() {
fetch('https://baconipsum.com/api/?type=meat-and-filler')
.then(response => response.json())
.then(paragraphs => this.setState({ paragraphs }));
}
componentDidUpdate(prevProps, prevState) {
const
curr = JSON.stringify(this.props.highlightWords),
prev = JSON.stringify(prevProps.highlightWords);
if (curr !== prev) {
this.setState({ regex: this._updateRegex(this.props.highlightWords) });
}
}
render() {
return (
<div>
{this.state.paragraphs.map(paragraph => (
<p dangerouslySetInnerHTML={{ __html: this._highlightWords(paragraph) }} />
))}
</div>
);
};
}
ReactDOM.render(<WordHighlighter highlightWords={highlightWords} />, document.querySelector("#app")).highlight { background: yellow; }<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>Aquí hay una implementación de componente de la clase anterior:
const { useEffect, useState } = React;
const words = ['beef', 'ham', 'pork', 'sausage', 'ribeye', 'ribs'];
const updateRegex = (words) =>
new RegExp(`\\b(${words.map(word => `(${word})`).join('|')})\\b`, 'gi');
const wordHighlighter = (paragraph, regex) =>
paragraph.replace(regex, `<span class="highlight">$1</span>`);
const WordHighlighter = (props) => {
const { highlightWords } = props;
const [ regex, setRegex ] = useState(updateRegex(highlightWords));
const [ paragraphs, setParagraphs ] = useState([]);
useEffect(() => fetch('https://baconipsum.com/api/?type=meat-and-filler')
.then(response => response.json())
.then(json => setParagraphs(json)), []);
useEffect(() => setRegex(updateRegex(highlightWords)), [highlightWords]);
return (
<div>
{paragraphs.map(paragraph => (
<p dangerouslySetInnerHTML={{ __html: wordHighlighter(paragraph, regex) }} />
))}
</div>
);
}
ReactDOM.render(<WordHighlighter highlightWords={words} />, document.querySelector("#app")).highlight { background: yellow; }<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>Respuesta #2
Aquí hay un ejemplo de lo que dije antes.
const par = "The quick brown fox jumped quickly over the lazy dog.";
const words = [
"quick",
"fox",
"over",
];
function matches(par, words){
const output = [];
words.forEach(word => {
const test = par.split(word);
if(test.length > 0){
for(let i = 1; i < test.length; i++){
output.push(word);
}
}
})
return output;
}
const ans = matches(par, words);
console.log(ans);