Practice

Here you found tasks which help in understanding regexp construction principles.

Replace all occurences of <img...> with <img.../> (add a slash).

var text = '<img src="a">   <img src="b" id="c"/>'

text = text.replace(... your replacement ... )

// now text = '<img src="a"*!*/*/!*>   <img src="b" id="c"/>'

Open solution
Solution

An IMG tag with attributes can be represented as <img.?>.

Now, how can we find an img, ending with /, but not with />? Think about it, maybe you can find a good way. At lease you’ll see which difficulties arise.

Another, easy and lazy way is to match <IMG.? in lazy mode until it ends with either /> or >, and then replace both types of tags with captured <IMG.*? plus />.

Here’s the solution:

var text = '<img src="a">   <img src="b" id="c"/>'

text = text.replace( /(<img.*?)\/?>/g, '$1/>' )

alert(text)

There’s a document which contains HTML tags, some of them in short form: <br> instead of <br/> and <img...> instead of <img.../>.

Make it XML valid.

Note that there can be both valid and invalid of a tag in the text.

Example:

var text = <br> <a href="#"><img src="a"></a>  <br/>  <br></br>'

After the replacement, the first and second tags should be closed:

text == '<br/> <a href="#"<img src="a"/></a>  <br/>  <br>  </br>'

P.S. In other words, close BR and IMG tags which are not closed.

Open hint 1
Hint 1
Open solution
Solution

First, we solve the task without self-closing tags <br/>.

We can do assume so, because self-closing tags can be replaced with non-closing tags with one more regexp, so 2 regexps would do the job anyway.

Finding a <br> without a following </br> requires a negative lookahead:

var re = /<br>(?!</br>)/

Let’s adapt this to IMG as well:

var re = /<(br|img).*?>(?!</\1>)/

To be really peculiar, we could add \b after tag name, to ensure that <brown> (or kind of) doesn’t match:

var re = /<(br|img)\b.*?>(?!</\1>)/

Now all we need to replace it, adding a closing slash:

text.replace(/<(br|img)\b(.*?)>(?!<\/\1>)/g, '<$1$2/>')

To support tags, which are already self-closing, we match optional / and put it out of the brackets, so tag body won’t contain it:

text.replace(/<(br|img)\b(.*?)*!*\/?*/!*>(?!<\/\1>)/g, '<$1$2/>')

The regexp above excludles closing / from tag body if there is any.

Finally, the solution:

var text = '*!*<br>*/!* <a href="#">*!*<img src="a">*/!*</a>  <br/>  <br></br>'

text = text.replace(/<(br|img)\b(.*?)\/?>(?!<\/\1>)/g, '<$1$2/>')

alert(text)

The tutorial is not finished. Till now, we have it up to this part…

Tutorial

Donate

Donate to this project