0

How can I use .replace() with regex for </?span>, as in this question? (this regex would ideally match <span> or </span>, including all things within the span)

I have tried a variety of examples, such as:

.replace(/</?span>/,"")

.replace(/</?span>/g,"")

.replace(/[</?span>]/,"")

.replace(/[</?span>]/g,"")
Community
  • 1
  • 1
maudulus
  • 10,627
  • 10
  • 78
  • 117
  • The question you linked has a perfectly fitting answer. – Katana314 Dec 22 '14 at 18:49
  • @Katana314 I agree, assuming that the person knows how to use `.match()` with regex in the first place – maudulus Dec 22 '14 at 18:50
  • Why use regex in the first place? Is the HTML destined for the page? It's easier and safer to remove the nodes than to mess with HTML parsing. – six fingered man Dec 22 '14 at 18:53
  • 1
    Just a caution in case it applies here - it is not recommended to parse html with regex. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – Wet Noodles Dec 22 '14 at 18:53
  • Why not make it a DOM collection, find the spans, and remove the elements? Clean and no need to deal with regular expressions. – epascarello Dec 22 '14 at 18:54
  • It's not even so much a matter of regex or not. It's a matter of manually parsing when the browser has a built-in parser that will be far more accurate and efficient. – six fingered man Dec 22 '14 at 18:55
  • can you provide an real example on what you want to achieve, with input and expected output. – hjl Dec 22 '14 at 18:55
  • What errors are you getting? Try `.replace(?span>,"")`, what do you get? Because "here" in `/`<-here + `?span>` +`/` <-here, are not part of the regex. –  Dec 22 '14 at 18:58
  • 2
    @sln: That's sure not going to work. –  Dec 22 '14 at 19:02
  • @squint - Yeah, but shouldn't the OP be answering that? –  Dec 22 '14 at 19:05
  • @sln: Answering what? You're giving the OP code that won't work. –  Dec 22 '14 at 19:06
  • @squint - What error do you get? And I was helping him solve his own problem without it being spoon fed. –  Dec 22 '14 at 19:13
  • @sln: If you don't want to spoon feed him, then why should I spoon feed you? If you want to know the error, then test your code. –  Dec 22 '14 at 19:18
  • @sln, it doesn't work. – maudulus Dec 22 '14 at 19:20
  • @maudulus- Try this one `.replace(/<(?:(?:\/?span\s*\/?)|(?:span\s+(?:(?:(?:"[\S\s]*?")|(?:'[\S\s]*?'))|(?:[^>]*?))+\s*\/?))>/g, "")` Report back. –  Dec 22 '14 at 19:49

4 Answers4

4

In Javascript you need to escape / because JS uses / as regex delimiters and add [^>]* to match anything in span:

.replace(/<\/?span[^>]*>/ig, "")
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

Problem with your code is the regular expression ends at the first /

.replace(/</?span>/,"")
           ^--Thinks this is the closing /

It would need to be escaped.

.replace(/<\/?span>/,"")
           ^ Use \ to escape it

But why use a regular expression to remove elements when it nested elements are going to cause you issues. Use the power of the DOM and do not rely on regular expressions.

function removeSpans(htmlStr) {
    var wrapper = document.createElement("div");
    wrapper.innerHTML = htmlStr;
    var spans = wrapper.getElementsByTagName("span");
    while(spans.length) {
      spans[0].parentNode.removeChild(spans[0]);
   }
   return wrapper.innerHTML;
}


var myHTML = "<span>This is a span</span> Some text <span>This is another span</span>";
var cleanedHTML = removeSpans(myHTML);
document.getElementById("out").innerHTML = cleanedHTML;
<div id="out"></div>

with jQuery:

function removeSpans(htmlStr) {
   var wrapper = $("<div/>").html(htmlStr);
   wrapper.find("span").remove();
   return wrapper.html();
}
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

I see that you included the jQuery tag in your question so I will assume that you can use jQuery. You could use jQuery to solve this issue.

$('span').each(function(){
   $(this).replaceWith($(this).text());
});

This will look for each span element, this element could be any of these:

<span>test</span>
<span class="has-a-class" id="also-an-id">a span with any number of attributes</span>

And replaces it with the text in that span, basically stripping the HTML tag and its attributes:

test
a span with any number of attributes
Sam Battat
  • 5,725
  • 1
  • 20
  • 29
0
.replace(/<\/?span.*?>/gi, "")

add ? after * to make it non-greedy match.

hjl
  • 2,794
  • 3
  • 18
  • 26
  • 1
    That's not going to make a difference. –  Dec 22 '14 at 19:04
  • @squint - Yeah, but shouldn't you tell him why? And, the reason is relative. –  Dec 22 '14 at 19:07
  • @sln: Shouldn't he tell why it *would* make a difference? –  Dec 22 '14 at 19:08
  • Here yes, because it matches for `[^>]*`. Personally I keeps non-greedy as a practice, : ] – hjl Dec 22 '14 at 19:08
  • @elaijuh - Its a tricky tradeoff, if its open-ended, the engine scans for the last `>` then works backwards, if it's not open-ended based on subsequent sub-expressions, it could still act in a greedy fashion. –  Dec 22 '14 at 19:12
  • @sin, can explain it on `/<\/?span.*?>/gi` ? – hjl Dec 22 '14 at 19:17
  • @squint, for your case, `/<\/?span[^>]*>/ig` doesn't work neither. – hjl Dec 22 '14 at 19:30
  • @elaijuh - Here is an example regex that can control those pesky `<>` characters. `<(?:(?:/?span\s*/?)|(?:span\s+(?:(?:(?:".*?")|(?:'.*?'))|(?:[^>]*?))+\s*/?))>` I don't think I could explain it. (Use dot-all modifier) –  Dec 22 '14 at 19:41
  • @elaijuh: I know that. See my comment above... http://stackoverflow.com/questions/27608650/difficulty-using-javascript-replace-function-with-regex#comment43639688_27608650 –  Dec 22 '14 at 19:47
  • @sin - im not gonna try tp understand that anyway thanks all the same :] – hjl Dec 22 '14 at 19:54