DEV Community

Cover image for Replacing a Dynamic Regex Match with the Same Number of Spaces
Raymond Camden
Raymond Camden

Posted on • Originally published at raymondcamden.com on

Replacing a Dynamic Regex Match with the Same Number of Spaces

This post is 100% thanks to my friend Peter Cooper. I couldn’t find any solutions online (or I may have Googled poorly) so I wanted to write this up in case other folks have the same problem. Imagine you have a string of HTML and you want to remove the tags. An easy solution would be something like this:

let s = `
<p>
This is Ray and I'm <i>very</i> cool. I sometimes am <b><i>super</i></b> cool!
</p>

Enter fullscreen mode Exit fullscreen mode

this is bad code!
and lots and lots


<ul>
<li>more</li>
<li>more</li>
</ul>
`.trim();

// replace all html
s = s.replace(/<.*?>/g,'');
console.log(s);

Enter fullscreen mode Exit fullscreen mode

This works perfectly well, but my situation was a bit different. I needed to pass the result of this to a tool that reported on misspellings. When it did, it would report on line numbers and columns. With my initial solution, the string no longer had text in the same spaces as it did before. It was close, but in a large file the differences became worse towards the end.

So my question how - given a regex that is dynamic in size (<.*?>), was there a way to replace with space characters of the same length?

When I searched for a solution, my focus was on a regex expression of some sort that could help. Turned out the answer was simple. As Peter pointed out, the replace function lets you specify a substring for the replacement or a function. This function is passed the matched string (along with other arguments) so you can easily check the length and return the right number of spaces. Here’s an example:

s = s.replace(/<.*?>/g,function(match) {
  return " ".repeat(match.length);
});

Enter fullscreen mode Exit fullscreen mode

Peter’s solution was actually a bit more concise. I love arrow functions, but when teaching, I still like to show the “old” way first. I still remember when arrow function syntax confused the heck out of me:

s = s.replace(/<.*?>/g, _=> ' '.repeat(_.length) );

Enter fullscreen mode Exit fullscreen mode

You can test this in the CodePen below.

Anyway, that’s it, and I hope this helps! Also take this as my one millionth time reminding my readers that the MDN Web Docs are the best damn resource on the Internet.

Header photo by Florian Olivo on Unsplash

Top comments (0)