Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Regex to match certain HTML attributes

Posted on 2006-11-27
7
Medium Priority
?
1,229 Views
Last Modified: 2013-11-19
Hi,

Regexes are sometimes quite challenging. I've been banging my head on this table for hours now and want to stop.  Please help me get rid of this headache!

I need to remove all style and class attributes in an HTML file whilst leaving all other attributes untouched.  I just need the regex for this - I've written a generic filter that uses the Regex,  but I just can't seem to get this one to work (I'm failing to get the regex to ignore other attributes between the tag and the style=...).

Given the following HTML (which came from pasting from the trully awful MS Werd - I really couldn't invent this rubbish if I tried!):

<H1 style="MARGIN: 0cm 0cm 0pt"><FONT color=#000000>blah blah<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></font></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify"><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:PlaceName w:st="on"><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">blah blah</SPAN></st1:PlaceName><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">

I need just the Regex and the Replacement strings.  It should:
 - remove (match) style and class attributes
 - work with and without quotes - note that 'Century Gothic' is wrapped with single quotes
 - assume the attribute quotes are "double" (or missing)
 - the attributes must be allowed to be in *any* order in the tag
 - all other attributes and tags must be left in situ

I've other regexes that clean the rest of the vomit - at least ten of them!

For a bonus,  if anyone has the name of the idiot who created the Werd HTML engine.....  I'd just love to write to his/her mother and tell her how her child is messing with people's heads:-)

Cheers,
0
Comment
Question by:GlennGilbert
  • 3
  • 3
7 Comments
 
LVL 10

Assisted Solution

by:xanius
xanius earned 400 total points
ID: 18027043
search:

(perl style regex):

\b(class|style)=("[^"]+?"|\S+)\s*

replace: nothing

Xanius
0
 
LVL 3

Author Comment

by:GlennGilbert
ID: 18027052
Cheers!

Could you add the angle brackets to make it specific for an HTML tag please.

0
 
LVL 3

Author Comment

by:GlennGilbert
ID: 18027079
I always seem to mess up when adding the more specific characters:

Yours:
  \b(class|style)=("[^"]+?"|\S+)\s*


Mine:
  <.*\b(class|style)=("[^"]+?"|\S+)\s*.*>
  Which,  needless to say,  doesn't work as it matches everything.
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 85

Accepted Solution

by:
ozo earned 1600 total points
ID: 18027153
$_=q<
<H1 style="MARGIN: 0cm 0cm 0pt"><FONT color=#000000>blah blah<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></font></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify"><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:PlaceName w:st="on"><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">blah blah</SPAN></st1:PlaceName><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">
>;

s/(<[^<>]*?)\b((class|style)=("[^"]+?"|\S+)\s*)+([^<>]*>)/$1$5/g;

print;
0
 
LVL 3

Author Comment

by:GlennGilbert
ID: 18027624
Fantastic - thank you!

My learning point... search for all characters that aren't a start < or end > tag - and do this using as few matches as possible - *?

I made a small change to capture the leadng space(s) before the span/class so it looks like this (the syntax is my underlying filter which this will be poked into):
<Filter>
(<[^<>]*?)\s*\b((class|style)=("[^"]+?"|\S+))+([^<>]*>)
</Filter>
<Replacement>
$1$5
</Replacement>


Input:
<H1 style="MARGIN: 0cm 0cm 0pt"><FONT color=#000000>blah blah<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></font></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify"><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:PlaceName w:st="on"><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">blah blah</SPAN></st1:PlaceName><SPAN style="FONT-SIZE: 10pt; COLOR: #ff9900; FONT-FAMILY: 'Century Gothic'">


Output:
<H1><FONT color=#000000>blah blah<SPAN>&nbsp; </SPAN></font></H1>
<P style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify"><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:PlaceName w:st="on"><SPAN>blah blah</SPAN></st1:PlaceName><SPAN>


And I'll just get on with clearing out the rest of the vomit - like the xml prologue, smart tag stuff, font tags, empty styles... the list seems to go on forever.

Cheers,
Glenn
0
 
LVL 10

Expert Comment

by:xanius
ID: 18027665
Glenn,

> Which,  needless to say,  doesn't work as it matches everything.

when such things happen, you generally have a too greedy regex. As in the examples above, as a thumbs of rule, put in a '?' after the '*' and '?'s.

0
 
LVL 10

Expert Comment

by:xanius
ID: 18027733
(Sorrry, I was crossposting)

<Filter>
(<[^<>]*?)\s*\b((class|style)=("[^"]+?"|\S+))+([^<>]*>)
</Filter>
<Replacement>
$1$5
</Replacement>

works perfectly as long as there are no other attribtes between 'class' and 'style'. If this is true youre ok. If not, you should rather try to use two regexes, the first to idetnify the tag and the secodn to work on it

Regex1:
<Filter>
(<[^<>]*?(?:class|style)=[^<>]*?>)
</Filter>
 Put "$1" into som variable, then apply the following regex in it with the global switch

Regex2:
<Filter>
\b(class|style)=("[^"]+?"|\S+)\s*
</Filter>
<Replacement>
</Replacement>

Cheers
Xanius
0

Featured Post

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
Suggested Courses

972 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question