简体   繁体   中英

Regular expression to remove HTML tags

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.

Using a regular expression to parse HTML is fraught with pitfalls. HTML is not a regular language and hence can't be 100% correctly parsed with a regex. This is just one of many problems you will run into. The best approach is to use an HTML / XML parser to do this for you.

Here is a link to a blog post I wrote awhile back which goes into more details about this problem.

That being said, here's a solution that should fix this particular problem. It in no way is a perfect solution though.

var pattern = @"<(img|a)[^>]*>(?<content>[^<]*)<";
var regex = new Regex(pattern);
var m = regex.Match(sSummary);
if ( m.Success ) { 
  sResult = m.Groups["content"].Value;

To turn this:

'<td>mamma</td><td><strong>papa</strong></td>'

into this:

'mamma papa'

You need to replace the tags with spaces:

.replace(/<[^>]*>/g, ' ')

and reduce any duplicate spaces into single spaces:

.replace(/\s{2,}/g, ' ')

then trim away leading and trailing spaces with:

.trim();

Meaning that your remove tag function look like this:

function removeTags(string){
  return string.replace(/<[^>]*>/g, ' ')
               .replace(/\s{2,}/g, ' ')
               .trim();
}

In order to remove also spaces between tags, you can use the following method a combination between regex and a trim for spaces at start and end of the input html:

    public static string StripHtml(string inputHTML)
    {
        const string HTML_MARKUP_REGEX_PATTERN = @"<[^>]+>\s+(?=<)|<[^>]+>";
        inputHTML = WebUtility.HtmlDecode(inputHTML).Trim();

        string noHTML = Regex.Replace(inputHTML, HTML_MARKUP_REGEX_PATTERN, string.Empty);

        return noHTML;
    }

So for the following input:

      <p>     <strong>  <em><span style="text-decoration:underline;background-color:#cc6600;"></span><span style="text-decoration:underline;background-color:#cc6600;color:#663333;"><del>   test text  </del></span></em></strong></p><p><strong><span style="background-color:#999900;"> test 1 </span></strong></p><p><strong><em><span style="background-color:#333366;"> test 2 </span></em></strong></p><p><strong><em><span style="text-decoration:underline;background-color:#006600;"> test 3 </span></em></strong></p>      

The output will be only the text without spaces between html tags or space before or after html: " test text test 1 test 2 test 3 ".

Please notice that the spaces before test text are from the <del> test text </del> html and the space after test 3 is from the <em><span style="text-decoration:underline;background-color:#006600;"> test 3 </span></em></strong></p> html.

So the HTML parser everyone's talking about is Html Agility Pack .

If it is clean XHTML, you can also use System.Xml.Linq.XDocument or System.Xml.XmlDocument .

可以使用:

Regex.Replace(source, "<[^>]*>", string.Empty);

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 (ie 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 :)

You can use already existing libraries to strip off the html tags. One good one being Chilkat C# Library .

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>

Here is the extension method I've been using for quite some time.

public static class StringExtensions
{
     public static string StripHTML(this string htmlString, string htmlPlaceHolder) {
         const string pattern = @"<.*?>";
         string sOut = Regex.Replace(htmlString, pattern, htmlPlaceHolder, RegexOptions.Singleline);
         sOut = sOut.Replace("&nbsp;", String.Empty);
         sOut = sOut.Replace("&amp;", "&");
         sOut = sOut.Replace("&gt;", ">");
         sOut = sOut.Replace("&lt;", "<");
         return sOut;
     }
}

Remove image from the string, using a regular expression in c# (image search performed by image id)

string PRQ=<td valign=\"top\" style=\"width: 400px;\" align=\"left\"><img id=\"llgo\" src=\"http://test.Logo.png\" alt=\"logo\"></td>

var regex = new Regex("(<img(.+?)id=\"llgo\"(.+?))src=\"([^\"]+)\"");

PRQ = regex.Replace(PRQ, match => match.Groups[1].Value + "");

Why not trying reluctant quantifier? htmlString.replaceAll("<\\\\S*?>", "")

(It's Java but the main thing is to show the idea)

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.

Here's an extension method I created using a simple regular expression to remove HTML tags from a string:

/// <summary>
/// Converts an Html string to plain text, and replaces all br tags with line breaks.
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
[Extension()]
public string ToPlainText(string s)
{

    s = s.Replace("<br>", Constants.vbCrLf);
    s = s.Replace("<br />", Constants.vbCrLf);
    s = s.Replace("<br/>", Constants.vbCrLf);


    s = Regex.Replace(s, "<[^>]*>", string.Empty);


    return s;
}

Hope that helps.

Select everything except from whats in there:

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

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM