skip to Main Content

I am using next.js. I have json file with a string:

{
  "title":"Just a text with <b>accent</b> inside",
}

I want get this string and return a string with <b> tag inside.
There is my function:

function parseTitle(title) {
  let match = title.match(/<b>(.*?)</b>/);
  let prev = match[0];
  let next = match[1];
  let result = title.replace(new RegExp(prev, 'g'), '<b>' + next + '</b>');
  return (
    result
  )
}

And, when I try to use it:

<h1>{parseTitle(votingInfo.title)}</h1>

Of course, I get a string without tags:

Just a text with <b>accent</b> inside

How to fix it?

2

Answers


  1. You can use dangerouslySetInnerHTML

    const App = () => {
        const str = "Just a text with <b>accent</b> inside";
    
        function parseTitle(title) {
          let match = title.match(/<b>(.*?)</b>/);
          let prev = match[0];
          let next = match[1];
          let result = title.replace(new RegExp(prev, 'g'), '<b>' + next + '</b>');
          return (
            result
          )
        }
    
        return (
            <div dangerouslySetInnerHTML={{ __html: parseTitle(str) }}>
            </div>
        )
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
  2. Edit: I thought I’d understood your question, but it seems you weren’t asking this. In any case, your parseTitle function doesn’t do anything — it just returns the string argument unchanged.

    Here’s an annotated version:

    function parseTitle(title) {
        let match = title.match(/<b>(.*?)</b>/)
        let prev = match[0] // "<b>accent</b>" (the full match)
        let next = match[1] // "accent" (the part of the match in parentheses)
    
        // replace "<b>accent</b>" with "<b>" + "accent" + "</b>"
        // (i.e. the exact same string)
        let result = title.replace(new RegExp(prev, 'g'), '<b>' + next + '</b>')
    
        // return the unchanged string
        return result
    }
    

    Original answer

    The logic of parseTitle is wrong. You can implement this using regex lookbehind and lookahead:

    function parseTitle(title) {
        return title.match(/(?<=<b>)[^<]+(?=</b>)/)?.[0] ?? ''
    }
    
    console.log(parseTitle("Just a text with <b>accent</b> inside")) // "accent"

    (?<=<b>) matches an opening <b> tag before the match; [^<]+ matches anything that isn’t an opening angle bracket; (?=</b>) matches a closing </b> tag after the match. Grabbing [0] from a RegExpMatchArray returns the whole matched substring.

    The function will return an empty string in case it fails to match anything in the title passed to it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search