x-ray
x-ray

Reputation: 123

Splitting string with HTML markup into separate objects using JS

I am trying to split different parts of a string into new objects depending on whether there is HTML markup. This is what I have tried, I have also tried with split(), however, I can't find a way to pull the content within the HTML markups.

const example = 'The lucky stars is an astrology themed <a href="/game/">game</a> and it consists of <strong>thousands of.</strong>'
const richTexts = [];

example.match(/\<.*?\>/g).forEach((e) => {
  if (e.includes('<a')) {
    richTexts.push({
       type: 'hyperlink',
       content: ''
    })
  } else if (e.includes('<strong') {
    richTexts.push({
       type: 'bold',
       content: ''
    })
  } else {
    richTexts.push({
       type: 'text',
       content: ''
    })
  }
})

console.log(richTexts);

Desired output is:

[
  {
    type: 'text',
    content: 'The lucky stars is an astrology themed '
  },
  {
    type: 'hyperlink',
    content: 'game'
  },
  {
    type: 'text',
    content: ' and it consists of '
  },
  {
    type: 'bold',
    content: 'thousands of.'
  }
]

Upvotes: 0

Views: 314

Answers (2)

AbsoluteBeginner
AbsoluteBeginner

Reputation: 2255

My suggestion:

const example = 'The lucky stars is an astrology themed <a href="/game/">game</a> and it consists of <strong>thousands of.</strong>';
const richTexts = [];
var strType;

example.split(/((?:[^\s<]*<\w[^>]*>[\s\S]*?<\/\w[^>]*>)+[^\s<]*)/).filter(Boolean).forEach(e => {

  strType = 'text';
  if (e.includes('<a')) {
    strType = 'hyperlink'
  } else if (e.includes('<strong')) {
    strType = 'bold'
  };

  richTexts.push({
    type: strType,
    content: strType === 'text' ? e : e.replace(/(<([^>]+)>)/g, '')
  });

});

console.log(richTexts);

Upvotes: 1

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23480

Not elegant but solve your example:

const example = 'The lucky stars is an astrology themed <a href="/game/">game</a> and it consists of <strong>thousands of.</strong>'
const richTexts = [];

const res = example.split('<')
res.forEach(r => {
  let obj = {}
  if(r.includes('>')) {
    if(r.includes('strong')){
      obj.type= "bold"
    } else if (r.includes('href')) {
      obj.type = "hyperlink"
    } else {
      obj.type = 'text'
    }
  } else {
    obj.type = 'text'
  }
  
  r = r.slice(r.indexOf('>') + 1, r.length)
  
  if(r.length) {
    obj.content = r
    richTexts.push(obj)
  }
})

console.log(richTexts)

Upvotes: 1

Related Questions