Regular expression to remove HTML tags

Viewed 74133

I am using the following Regular Expresion to remove html tags from a string. It works except I leave the closing tag. If I attempt to remove: <a href="blah">blah</a> it leaves the <a/>.

I do not know Regular Expression syntax at all and fumbled through this. Can someone with RegEx knowledge please provide me with a pattern that will work.

Here is my code:

  string sPattern = @"<\/?!?(img|a)[^>]*>";
  Regex rgx = new Regex(sPattern);
  Match m = rgx.Match(sSummary);
  string sResult = "";
  if (m.Success)
   sResult = rgx.Replace(sSummary, "", 1);

I am looking to remove the first occurence of the <a> and <img> tags.

16 Answers

Strip off HTML Elements (with/without attributes)

/<\/?[\w\s]*>|<.+[\W]>/g

This will strip off all HTML elements and leave behind the text. This works well even for malformed HTML elements (i.e. elements that are missing closing tags)

Reference and example (Ex.10)

If you need to find only the opening tags you can use the following regex, which will capture the tag type as $1 (a or img) and the content (including closing tag if there is one) as $2:

(?:<(a|img)(?:\s[^>]*)?>)((?:(?!<\1)[\s\S])*)


In case you have also closing tag you should use the following regex, which will capture the tag type as $1 (a or img) and the content as $2:

(?:<(a|img)(?:\s[^>]*)?>)\s*((?:(?!<\1)[\s\S])*)\s*(?:<\/\1>)

Basically you just need to use replace function on one of above regex, and return $2 in order to get what you wanted.

Short explanation about the query:

  • ( ) - is used for capturing whatever matches the regex inside the brackets. The order of the capturing is the order of: $1, $2 etc.
  • ?: - is used after an opening bracket "(" for not capturing the content inside the brackets.
  • \1 - is copying capture number 1, which is the tag type. I had to capture the tag type so closing tag will be consistent to the opening one and not something like: <img src=""> </a>.
  • \s - is white space, so after opening tag <img there will be at least 1 white space in case there are attributes (so it won't match <imgs> for example).
  • [^>]* - is looking for anything but the chars inside, which in this case is >, and * means for unlimited times.
  • ?! - is looking for anything but the string inside, kinda similar to [^>] just for string instead of single chars.
  • [\s\S] - is used almost like . but allow any whitespaces (which will also match in case there are new lines between the tags). If you are using regex "s" flag, then you can use . instead.

Example of using with closing tag: https://regex101.com/r/MGmzrh/1

Example of using without closing tag: https://regex101.com/r/MGmzrh/2


Regex101 also has some explanation for what i did :)

If all you're trying to do is remove the tags (and not figure out where the closing tag is), I'm really not sure why people are so fraught about it.

This Regex seems to handle anything I can throw at it:

<([\w\-/]+)( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* *>

To break it down:

  • <([\w\-/]+) - match the beginning of the opening or closing tag. if you want to handle invalid stuff, you can add more here
  • ( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* - this bit matches attributes [0, N] times (* at then end)
    • +[\w\-]+ - is space(s) followed by an attribute name
    • (=(('[^']*')|("[^"]*")))? - not all attributes have assignment (?)
      • ('[^']*')|("[^"]*") - of the attributes that do have assignment, the value is a string with either single or double quotes. It's not allowed to skip over a closing quote to make things work
  • *> - the whole thing ends with any number of spaces, then the closing bracket

Obviously this will mess up if someone throws super invalid html at it, but it works for anything valid I've come up with yet. Test it out here:

const regex = /<([\w\-/]+)( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* *>/g;

const byId = (id) => document.getElementById(id);

function replace() {
console.log(byId("In").value)
  byId("Out").innerText = byId("In").value.replace(regex, "CUT");
}
Write your html here: <br>
<textarea id="In" rows="8" cols="50"></textarea><br>
<button onclick="replace()">Replace all tags with "CUT"</button><br>
<br>
Output:
<div id="Out"></div>

Simple way,

String html = "<a>Rakes</a> <p>paroladasdsadsa</p> My Name Rakes";

html = html.replaceAll("(<[\\w]+>)(.+?)(</[\\w]+>)", "$2");

System.out.println(html);

This piece of code could help you out easily removing any html tags:

import re
string = str(<a href="blah">blah</a>)
replaced_string = re.sub('<a.*href="blah">.*<\/a>','',string) // remember, sub takes 3 arguments.

Output is an empty string.

Select everything except from whats in there:

(?:<span.*?>|<\/span>|<p.*?>|<\/p>)

enter image description here

Related