如何使用值数组突出显示段落中的文本?

Pro*_*fer 1 javascript reactjs

我有值数组

const tags = ['Hello', 'moment', 'somewhere'];
Run Code Online (Sandbox Code Playgroud)

以及我的反应组件中显示的段落

const paras = [{
  text: 'Hello, tina. Thank you for all waiting. Hello?'
}, {
  text: 'When can I go? Okay. One moment. Let me just'
}, {
  text: 'if I can help you somewhere, if you are interested'
}]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我想用标签元素突出显示段落单词。并且只需要在突出显示的单词之前和之后几个单词,就像在第一句话中我只需要显示一样

 *One **moment**. Let *
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

我尝试过的:

getHighlightedText(text, highlight) {
    // Split text on highlight term, include term itself into parts, ignore case
    const parts = text.split(new RegExp(`(${highlight})`, 'gi'));
    return <span>{parts.map(part => part.toLowerCase() === highlight.toLowerCase() ? <span className="highlight">{part}</span> : part)}</span>;
  }

{
  paras.map((para) => {
    return (
      <Row key={para._id}>
        <Col md={11}>
          <div className="record">
            <p className="mb-0">
              {this.getHighlightedText(para.text, "hello")}
            </p>
          </div>
        </Col>
        <Col md={1}>
          <Button className="buttonLink" color="link">
            <b>{"View >"}</b>
          </Button>
        </Col>
      </Row>
    );
  });
}
Run Code Online (Sandbox Code Playgroud)

dec*_*ele 5

这是一个超级简单的可重用组件,用于通过标签突出显示文本:

function Highlight({ children: text = "", tags = [] }) {
  if (!tags?.length) return text;
  const matches = [...text.matchAll(new RegExp(tags.join("|"), "ig"))];
  const startText = text.slice(0, matches[0]?.index);
  return (
    <span>
      {startText}
      {matches.map((match, i) => {
        const startIndex = match.index;
        const currentText = match[0];
        const endIndex = startIndex + currentText.length;
        const nextIndex = matches[i + 1]?.index;
        const untilNextText = text.slice(endIndex, nextIndex);
        return (
          <span key={i}>
            <mark>{currentText}</mark>
            {untilNextText}
          </span>
        );
      })}
    </span>
  );
}

export default function App() {
  return (
    <div className="App">
      <h1>
        <Highlight tags={["Hel", "co", "nd"]}>Hello CodeSandbox</Highlight>
      </h1>
      <h2>
        <Highlight tags={["ditin", "e"]}>
          Start editing to see some magic happen!
        </Highlight>
      </h2>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

Codesndbox 中的演示

示例代码输出

将其与您的示例一起使用:

const tags = ["Hello", "moment", "somewhere"];
const paras = [
  {
    text: "Hello, tina. Thank you for all waiting. Hello?"
  },
  {
    text: "When can I go? Okay. One moment. Let me just"
  },
  {
    text: "if I can help you somewhere, if you are interested"
  }
];
function ParasList() {
  return (
    <ul>
      {paras.map((para, i) => (
        <li key={i}>
          <Highlight tags={tags}>{para.text}</Highlight>
        </li>
      ))}
    </ul>
  );
}
Run Code Online (Sandbox Code Playgroud)

示例代码#2 输出

解释:

Highlight组件很容易使用,您只需环绕一些文本,然后添加“tags”属性即可:<Highlight tags={["some"]}>some text</Highlight>

在组件内部,我使用了新的、闪亮的string.prototype.matchAll函数,它为我们提供了有关匹配项和找到它的索引的信息。

另外,我正在标签上使用正则表达式join("|"),因此它们之间具有“OR”关系。该标志i使突出显示不区分大小写,但如果您想保持区分大小写,可以将其删除。该g标志是全局标志,因此会找到并突出显示重复的匹配项。它在 matchAll 搜索中是必需的。

最后,我使用<mark>html 标签来突出显示,但您可以轻松更改它,甚至可以通过 props 传递自定义标签以获得更多功能。您还可以用常规跨度将“标记”位括起来,并用“突出显示”类名标记它们,并使用 CSS 以这种方式自定义外观。