Home > database >  Removing html tags from string in React
Removing html tags from string in React

Time:12-04

I am trying to remove tags from a string but keeping the order in tact using Regular expression. The string I have is this

<p><span style="color: blue;">General Power</span></p><p>This contains some info.</p><p><br></p><p>!</p><p>enable</p><p>bus at</p><p>terminal: <span style="color: red;">Name&nbsp;Terminal</span></p><p>enable bus name <span style="color: red;">Switch Bus</span></p><p>no ip domain-lookup</p><p><span style="color: rgb(0, 0, 0);">ip domain name </span><span style="color: red;">region</span><span style="color: rgb(0, 0, 0);">.google.com</span></p><p><br></p><p>!</p>

What I have tried so far is

 const [string, setString] = useState(
    `<p><span style="color: blue;">General Power</span></p><p>This contains some info.</p><p><br></p><p>!</p><p>enable</p><p>bus at</p><p>terminal: <span style="color: red;">Name&nbsp;Terminal</span></p><p>enable bus name <span style="color: red;">Switch Bus</span></p><p>no ip domain-lookup</p><p><span style="color: rgb(0, 0, 0);">ip domain name </span><span style="color: red;">region</span><span style="color: rgb(0, 0, 0);">.google.com</span></p><p><br></p><p>!</p>`
  );

  useEffect(() => {
    const regex = /(<([^>] )>)/gi;
    const newString = string.replace(regex, " ");
    setString(newString);
  }, []);

What I get is this

General Power This contains some info. ! enable bus at terminal: Name Terminal enable bus name Switch Bus no ip domain-lookup ip domain name region .google.com !

The order I want is:

General Power

This contains some info.

!

enable

bus at

terminal: Name Terminal

enable bus name Switch Bus

no ip domain-lookup

ip domain name region.google.com

!

 const [string, setString] = useState(
    `<p><span style="color: blue;">General Power</span></p><p>This contains some info.</p><p><br></p><p>!</p><p>enable</p><p>bus at</p><p>terminal: <span style="color: red;">Name&nbsp;Terminal</span></p><p>enable bus name <span style="color: red;">Switch Bus</span></p><p>no ip domain-lookup</p><p><span style="color: rgb(0, 0, 0);">ip domain name </span><span style="color: red;">region</span><span style="color: rgb(0, 0, 0);">.google.com</span></p><p><br></p><p>!</p>`
  );

  useEffect(() => {
    const regex = /(<([^>] )>)/gi;
    const newString = string.replace(regex, " ");
    setString(newString);
  }, []);

This is what I have tried so far

CodePudding user response:

To preserve the order of the lines, you can use the String.prototype.split() method to split the string by the

tags, and then use String.prototype.replace() to remove the remaining HTML tags from each line.

Here is an example of how you could do this:

const [string, setString] = useState(
  `<p><span style="color: blue;">General Power</span></p><p>This contains some info.</p><p><br></p><p>!</p><p>enable</p><p>bus at</p><p>terminal: <span style="color: red;">Name&nbsp;Terminal</span></p><p>enable bus name <span style="color: red;">Switch Bus</span></p><p>no ip domain-lookup</p><p><span style="color: rgb(0, 0, 0);">ip domain name </span><span style="color: red;">region</span><span style="color: rgb(0, 0, 0);">.google.com</span></p><p><br></p><p>!</p>`
);

useEffect(() => {
  // Split the string by the `<p>` tags
  const lines = string.split("<p>");

  // Use `String.prototype.replace()` to remove the remaining HTML tags from each line
  const newString = lines.map(line => line.replace(/(<([^>] )>)/gi, " ")).join("\n");

  // Set the new string
  setString(newString);
}, []);

This should give you the output you are looking for:

Copy code
General Power
This contains some info.

!
enable
bus at
terminal: Name Terminal
enable bus name Switch Bus
no ip domain-lookup
ip domain name region.google.com

!

CodePudding user response:

DOMParser combined with a method to retrieve all text nodes would be more appropriate. And rather than an effect hook for this, consider passing a function to useState - that way, the state never gets set to the (undesirable) value with the HTML markup, but starts out as the replaced string without any re-renderings - or avoid state entirely now that it isn't being set anywhere.

const getTextContentOnly = (html) => {
  const doc = new DOMParser().parseFromString(html, 'text/html');
  const walker = document.createTreeWalker(
        doc.body, 
        NodeFilter.SHOW_TEXT, 
        null, 
        false
    );
    const texts = [];
    let node;
    while(node = walker.nextNode()) {
        texts.push(node.nodeValue);
    }
    return texts;
}
const App = () => {
     const texts = React.useMemo(() => getTextContentOnly(
    `<p><span style="color: blue;">General Power</span></p><p>This contains some info.</p><p><br></p><p>!</p><p>enable</p><p>bus at</p><p>terminal: <span style="color: red;">Name&nbsp;Terminal</span></p><p>enable bus name <span style="color: red;">Switch Bus</span></p><p>no ip domain-lookup</p><p><span style="color: rgb(0, 0, 0);">ip domain name </span><span style="color: red;">region</span><span style="color: rgb(0, 0, 0);">.google.com</span></p><p><br></p><p>!</p>`
    ), []);
    return texts.map((text, i) => <div key={i}>{text}</div>);
};

ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

  • Related