【问题标题】:Javascript/react - highlight matching parenthesisJavascript/react - 突出显示匹配的括号
【发布时间】:2021-10-05 00:13:02
【问题描述】:

今天我遇到了在 React 中突出显示匹配括号的问题。这是示例文本:

(my text (is here and) I want (to highlight (something here)))

我希望它在代码编辑器中看起来像,我的意思是: image attached

我尝试使用react-process-string:

processString([
      {
        regex: /\(|\)/g,
        fn: (key, result) => this.colorBracket(key, result[0])
      }
])(value);

colorBracket = (key, result) => {
    const { usedColors } = this.state;

    const bracketColors = ['red', 'green', 'yellow', 'blue', 'purple'];

    let newColor = '';
    if (result === '(') {
      newColor =
        usedColors.length
          ? bracketColors[usedColors.length]
          : bracketColors[0];

      if (!usedColors.includes(newColor)) {
        this.setState({ usedColors: [...usedColors, newColor] });
      }
    } else {
      newColor = usedColors.length
        ? usedColors[usedColors.length - 1]
        : bracketColors[0];

      if (usedColors.length) {
        this.setState({ usedColors: usedColors.filter(e => e !== newColor) });
      }
    }

    return <span style={{ color: newColor }}>{result}</span>;
  };

但我遇到了react maximum update depth 的问题。

有没有可能做的更简单,不用更新状态等等?

【问题讨论】:

    标签: javascript reactjs regex


    【解决方案1】:

    当然,一旦你知道了正确的工具,这并不难。

    这是我整理的CodeSandbox example,以及下面相同的 sn-p(针对 Stack Overflow 的古老 Babel 版本稍作调整)。

    想法是:

    • 使用string.split 的正则表达式模式将字符串拆分为括号或不是括号的片段
    • 遍历这些片段以跟踪括号的嵌套级别(以正确着色对)
    • 最后,返回一个带有这些子元素的 React 片段(这样我们就不必处​​理数组键了)

    本示例中的颜色只有 3 级深,但您可以轻松添加更多,或使用模数运算符在 N 种颜色上进行着色循环。

    function BracketHighlighter({ text }) {
      const children = React.useMemo(() => {
        const out = [];
        let level = 0;
        text.split(/([()])/).forEach((bit) => {
          if (bit === "(") {
            level++;
            out.push(<span className={"l" + level}>{bit}</span>);
          } else if (bit === ")") {
            out.push(<span className={"l" + level}>{bit}</span>);
            level--;
          } else {
            out.push(bit);
          }
        });
        return out;
      }, [text]);
      return React.createElement(React.Fragment, {}, ...children);
    }
    
    function App() {
      const [text, setText] = React.useState(
        "(my text (is here and) I want (to highlight (something here)))"
      );
      return (
        <div className="App">
          <input value={text} onChange={(e) => setText(e.target.value)} />
          <br />
          <BracketHighlighter text={text} />
        </div>
      );
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    .l1 {
      background-color: orange;
    }
    
    .l2 {
      background-color: lightgreen;
    }
    
    .l3 {
      background-color: cyan;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

    • 非常感谢。一如既往,我没有考虑非常基本的事情(forEach,递增/递减):)
    猜你喜欢
    • 2010-09-18
    • 2014-05-01
    • 2015-08-21
    • 2020-06-05
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多