reactjs - Extrage/Potrivește cuvinte specifice dintr-un paragraf în JavaScript
În prezent lucrez la un proiect React Native (bazat pe JS) în care trebuie să potrivesc și să extrag numele spitalelor din paragrafe dinamice provenite de la serverul backend. Cunosc metodele match(), includes() etc., dar acestea nu funcționează în acest caz deoarece numele sunt dinamice și pot conține mai multe cuvinte.
Vreo sugestie!
Răspuns #1
Poți evidenția cuvintele la redarea textului HTML.
O expresie regulată poate fi creată dintr-o listă de cuvinte prin:
const regex = new RegExp(`\\b(${words.map(word => `(${word})`).join('|')})\\b`, 'gi');
HTML-ul brut poate fi setat folosind proprietatea dangerouslySetInnerHTML a elementului <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>Iată o implementare a componentei pentru clasa de mai sus:
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>Răspunsul #2
Iată un exemplu a ceea ce am spus mai devreme.
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);