-2

I have a string with HTML code:

let string = '<span><p>Hello</p></span>';

I want to change all the substrings between < and > to a div element. Here is the desired result:

let desired = '<div><div>Hello</div></div>';

Sort of like .replace(), except the inside of the <> could be anything.

Please avoid Regex if possible. Thanks!

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Halo
  • 1,730
  • 1
  • 8
  • 31

1 Answers1

4

You asked for a non regex solution, but this is a perfect application of regex. /<(\/?)\w+>/g is the first one to come to me.

Parsing html with regex is not a good idea, but in this case it seems fine for a known set of inputs.

Replace can be used with regex to target any string that matches a pattern, and replace part of it with something else.

Here is a code example using the above regex:

const regex = /<(\/?)\w+>/g
const subst = `<$1div>`

const tagToDiv = (str) => str.replace(regex, subst)

const str1 = `<span><p>Hello</p></span>`
const str2 = `regex should not parse html <yes> <no>`

console.log({str1, result: tagToDiv(str1)})
console.log({str2, result: tagToDiv(str2)})

If you don't want to use regex, you can parse the string character by character, but this will perform badly, with more complexity.

Isaac
  • 56
  • 4
  • 1
    If you want to get more comfortable with regex, https://regex101.com/ can be a very helpful tool -- put it into ecmascript mode to test your regex in real time. – Isaac Sep 25 '22 at 01:31
  • how would I get the value the tag? For example, how would I get `span` before changing it to `div`? In your example, it is replacing the tags directly, but is there a way to see what is being changed to `div`? – Halo Sep 25 '22 at 03:13
  • @Anye you can edit your question or ask a new one based on this -- I don't understand exactly what you mean by "get `span`". If you enclose `\w+` in a group, like `(\w+)` its contents will be stored to `$2`. If you want to use logic to decide how to handle different group values, you can [use a function instead of a string for the replacement value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace). – Isaac Sep 25 '22 at 03:16
  • How would I go about using `/w+` with the regex you provided? – Halo Sep 25 '22 at 03:18
  • I basically want to create a `span` element around the substring between `<` and `>` – Halo Sep 25 '22 at 03:21
  • The comment section doesn't let me use all the formatting I'd like to answer this question, but the regex I provided already uses `/w+`. `/w+` matches one or more word characters. By wrapping it in parenthesis, it becomes a capturing group. When doing replacement, `$n` refers to the value in a capturing group by index. The original regex uses a capturing group around the optional backslash, to include said backslash in the replacement. The regex `/<(\/?)(\w+)>/g` would have a group for the backslash and a group for the tag name. – Isaac Sep 25 '22 at 03:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/248329/discussion-between-isaac-and-anye). – Isaac Sep 25 '22 at 03:23