开发者

Replacing html font tag using regex

开发者_开发技巧

I would like to replace (all occurences) of the HTML <font>-tag in a string.

Example string:

Line1<div><font class="blablabla" color="#33FF33">Line2</font></div><div>Line3

or:

Line1<div><font color="#33FF33">Line2</font></div><div><font color="#FF3300">Li</font>ne3

The font (starttag) should be replaced by the color, so that based on the two examples we get:

Line1<div>33FF33Line2</font></div><div>Line3
Line1<div>33FF33Line2</font></div><div>FF3300Li</font>ne3

I've tried the following (among others :P):

preg_replace('/<font.*color="#([0-9a-fA-F]){6}">/', '{1}', $string)

I think I'm in the right direction, however I think it's more like so close yet so far away :)

When I use it on the string with only 1 fonttag in it, it removes the font tag (I must have messed something up with the replacement {1}). When I use it on the string with multiple fonttags in it, it does the same. But not only removing the first fonttag but everything from the first fonttag to the next (or last) fonttag.

Ok.

Let's just forget about the HTML code parsing discussion for a sec.

What if I had the following texts:

This colorcode (#333333) is so cool
This colorcode (orange: #ff3300) is way cooler

And I wanted the texts to become:

This colorcode 333333 is so cool
This colorcode ff3300 is way cooler

Same situation as I see it, or am I being ignorant now?


preg_replace('~<font[^>]*\scolor="#([0-9a-fA-F]{6})"[^>]*>~', '$1', $string);

* and other quantifiers are greedy by default, which is why you got the unintended contraction of the string with multiple font tags; it's just matching too much. You can make them non-greedy by adding a question mark (.*?), but other factors can still cause them to consume more than you want. It's better in this case to use a more specific expression ([^>]*) that can't match beyond the tag it starts in.

Besides that, in the code you posted you were using {1} instead of $1 for the backreference, and you had the quantifier ({6}) outside the parentheses, so you would only ever capture the last digit, not all six as you intended. That code shouldn't have returned the result you posted, to say nothing of the correct result.

As for your updated question:

preg_replace('~\([^)]*#([0-9a-fA-F]{6})[^)]*\)~', '$1', $string);


RegEx is nice and convenient, but I would question whether or not you could catch every case using RegEx. What about tags within strings, etc?

I wrote some spidering code and ended up just parsing the entire document, element by element. That was the only way I found to make it reliable.

See: http://blackbeltcoder.com/Articles/strings/parsing-html-tags-in-c/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜