Challange: Convert HTML Enteties

Hej!

I’m having some issues with the Converting HTML enteties and would like to ask for your input.

my code is as follows:

function convertHTML(str) {
  let regExp = /&|"|'|<|>/g
  let htmlObj1 = {
    "&": "&amp;",
    '<': "&lt;",
    '>': "&gt;",
    '"': "&quot;",
    "'": "&apos;"
  }

console.log(str.replace(regExp,htmlObj1[str.match(regExp)]))
return str.replace(regExp,htmlObj1[`${str.match(regExp)}`])

}

I’ve tested my regExp in a simulator and it should match all 5 of the entities, however when i run the tests i fail on ‘>’ and ’ " ', which is kinda weird. How can i pass ‘<’ but fail ‘>’ ?

EDIT:

I’ve made some progress as my understanding is that I included /g-flag in both the regexp and what to replace, which created issues for multiple instances of one character. Now I’ve fixed that, although the issue that remains is that my program fail on the ‘<>’ test.

my code prints “&lt&lt” instead of"&lt&gt"

function convertHTML(str) {
  let htmlObj1 = {
    "&": "&amp;",
    '<': "&lt;",
    '>': "&gt;",
    '\"' : "&quot;",
    "'": "&apos;"
  }

console.log(str.replace(/[&\>\"\<\']/g,htmlObj1[str.match(/[&\>\"\<\']/)]))
return str.replace(/[&>\"<\']/g,htmlObj1[str.match(/[&>\"<\']/)])

}

@MSPa1nT
You have used g flag in the front of the code but you missed those in the match function.
But the main problem is that the str argument may contain many characters that you need to change to HTML Entities, so that when the string contain many of those characters the match function return those as a array.

EDIT:
So, that the native codes can’t find the specific key to return value.

Hope This Help

1 Like

Hej AndrewAung11,

Thanks for the input, although making the str into an array is just one of many solutions.
For example, there’s a solution like the one below where a conversion is not taking place.

function convertHTML(str) {
  // Use Object Lookup to declare as many HTML entities as needed.
  const htmlEntities = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&apos;"
  };
  // Using a regex, replace characters with it's corresponding html entity
  return str.replace(/([&<>\"'])/g, match => htmlEntities[match]);
}

// test here
convertHTML("Dolce & Gabbana");

The issue with my code is only the “<>” part, it manages everything else. Somehow it reads them as doubles of the same character , depending on how i define the regExp , which is not making sense to me.

@MSPa1nT
Try testing like this:

function convertHTML(str) {
  let htmlObj1 = {
    "&": "&amp;",
    '<': "&lt;",
    '>': "&gt;",
    '\"' : "&quot;",
    "'": "&apos;"
  }

  return str.replace(/[&>\"<\']/g, htmlObj1[str.match(/[&>\"<\']/)])
}

console.log(convertHTML(`&<>"'`))

I think you had misunderstood.
You will see the console outputting &amp;&amp;&amp;&amp;&amp;.

1 Like

Exactly ,
The issue seems to be with that if several matches comes after each other, they take on the expression of the first match. Still not sure what the solution is :confused:

@MSPa1nT
Hint:
Try using .map function.

I’ve solved it with .map function, but I’m interested in making my initial code work.

compare the second argument to str.replace() of your solution and the working solution.
htmlObj1[str.match(/[&\>\"\<\']/)]
vs
match => htmlEntities[match]

In your case, as a key in the html object you call another match() which will always return the first matched case. In '<>'.match(/[&\>\"\<\']/) it will always return <. However cases the replace method works with, it will always replace the with the first match.

In the working solution we have an inline arrow function. Its takes what replace matches as parameter and calls the html object with that parameter. So when replace provides the first match < it uses this as key on html object. Then replaces provides > as symbol to be replaced and its what the function passes to the html object

EDIT: the regex bracket notation for range of items [items] dont require symbols to be preceded by \ . It reads all symbols explicitly, only / would be used as \/, or it will close the regular expression in JS. So /[&\>\"\<\']/ can be put as /[&>"<']/

1 Like

Thanks @Sylvant & @AndrewAung11 !

Reading up further on the documentation it’s my understanding that replace can take a function-argument in it’s second parameter, in which the user defines a variable-name which will be matched with the regExp-match.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.