By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,717 Members | 1,320 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,717 IT Pros & Developers. It's quick & easy.

preg_replace_callback() with create_function() and awkward strings

P: n/a
Hi all,

I'm trying to write a PHP colour parser and after various attempts,
something, somewhere trips it over. Some details:
String to parse:

$origString = '^1foo^5bar';
Required output:

<span style="color:#F00; background-color:transparent;">foo</span>
<span style="color:#F0F; background-color:transparent;">bar</span>
I have an array with all the HTML colour codes:

$cssColours = array(
'#000', '#F00', '#3F0', '#FF0',
'#00F', '#F0F', '#0FF', '#FFF', '#0E0'
);
One method I tried was:

$length = strlen($string);
for ($i = 0; $i < $length; $i++) {
if ($string[$i] == '^') {
if (is_numeric($string[$i + 1])) {
if (intval($string[$i + 1]) < 9) {
if (!$colour) {
$string = str_replace(
$string[$i] . $string[$i + 1],
'<span style="color:' . $cssColours[$string[$i + 1]] .
'; background-color:transparent;">',
$string
);
$colour = true;
} else {
$string = str_replace(
$string[$i] . $string[$i + 1],
'</span><span style="color:' . $cssColours[$string[$i + 1]] .
'; background-color:transparent;">',
$string
);
}
}
}
}
}
This "sort of" works although if the original string contains '^0' as a
colour code, no closing </span> tag is added (seems to work for all
other colours) but the other downside to this method is it's slow.

I then had a look at some regex that I thought might work. The code I
have for this is:
$string = stripslashes(substr(preg_replace_callback(
'`(?:\^([0-8]))`',
create_function(
'$matches',
'$cssColours = array("#000", "#F00", "#3F0", "#FF0", "#00F", "#F0F",
"#0FF", "#FFF", "#0E0"); return "</span><span style=\"color:" .
$cssColours[$matches[1]] . ";\">";'
),
quotemeta($string)
), 7)) . '</span>';
I know this is really tacky looking and it fails in some cases. When
feeding this:
echo $lfs->parseColourCodes('^0[^1TST^0]^1M^^0ike');
it produces (formatted for Usenet):
<span style="color:#000;">[</span>
<span style="color:#F00;">TST</span>
<span style="color:#000;">]</span>
<span style="color:#F00;">M^</span>
<span style="color:#000;">ike</span>
which is what I was expecting it to output. However, feeding it:
echo $lfs->parseColourCodes('^^^[^TST]M^^ike');
for example gives me:
^TST]M^^ike</span>
which is obviously not what I'm after =)

Someone did send me a solution they wrote but there's a whole class for
it alone (the code I'm writing is just a function within a class) and
was wondering if anyone had any ideas on this that might be solved with
a "simple" regex?

The legal colour codes that can be parsed are:
^0 - ^8
but ^ chars are perfectly ok just as carets(^boo^ etc).

The part I'm not understanding atm, is why the beginning of the string
is disappearing but it seems to be some kind of "pattern". For example,
feeding it this:
echo $lfs->parseColourCodes('^[^TST]M^^ike');
gives me:
T]M^^ike</span>
I've tried with and without the quotemeta() call (there can be pretty
much any symbolic char, so wasn't sure what might screw over the regex
pattern) but it's just not happening for me.

If anyone has any ideas / thoughts / suggestions, I'd be grateful in
hearing them as right now, I'm pretty stumped =)
TIA.

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/
Jul 17 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Ian.H wrote:
String to parse:

$origString = '^1foo^5bar';
Required output:

<span style="color:#F00; background-color:transparent;">foo</span>
<span style="color:#F0F; background-color:transparent;">bar</span>
[ ... ]

$string = preg_replace_callback(
'`\^([0-8])(.*?)(?=(?:\^[0-8])|\z)`',
create_function(
'$matches',
'$cssColours = array("#000", "#F00", "#3F0", "#FF0",
"#00F", "#F0F", "#0FF", "#FFF", "#0E0");
return "<span
style=\"color:{$cssColours[$matches[1]]};\"{$matches[2]}</span>";'),

$string);

See ciwas for arguments against inline styles.

HAGW!

--
Jock
Jul 17 '05 #2

P: n/a
On Fri, 15 Oct 2004 11:56:26 +0100, John Dunlop
<us*********@john.dunlop.name> wrote:
Ian.H wrote:
String to parse:

$origString = '^1foo^5bar';
Required output:

<span style="color:#F00; background-color:transparent;">foo</span>
<span style="color:#F0F; background-color:transparent;">bar</span>


[ ... ]

$string = preg_replace_callback(
'`\^([0-8])(.*?)(?=(?:\^[0-8])|\z)`',
create_function(
'$matches',
'$cssColours = array("#000", "#F00", "#3F0", "#FF0",
"#00F", "#F0F", "#0FF", "#FFF", "#0E0");
return "<span
style=\"color:{$cssColours[$matches[1]]};\"
>{$matches[2]}</span>";'),

$string);

See ciwas for arguments against inline styles.

HAGW!

Ahh John you're a diamond!

The only reason I opted for the create_function() call was because it
failed every time I tried to use either:
$this->someFunction()

or

FOO::someFunction()
I've never actually used this function before.. it came as a result of
using an array in preg_replace():
$string = preg_replace('/pattern/', "{$cssCodes[$1]}", $string);
and all other variations I could think of failing.

If there's a better way, I'm all for hearing! I didn't think this was
anywhere near a "perfect" solution.. just a possible solution =)

Thanks again for your answer.. I can now retain some hairs =D

Regards & good weekend to yourself...

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/
Jul 17 '05 #3

P: n/a
On Fri, 15 Oct 2004 11:58:35 GMT, Ian.H <ia*@WINDOZEdigiserv.net> wrote:
[ snip ]
See ciwas for arguments against inline styles.

HAGW!


The only reason I opted for the create_function() call was because it
failed every time I tried to use either:


[ ... SNIP ... ]
Oops! I really misinterpreted this heh (it was late, very).

I don't use inline styles under normal circumstances, but this class is
being written for a "gaming community".. so I don't know what styles
they may / may not already have or want. This is also pretty much the
first release of this code and have thought about moving certain things
into a CSS file but don't know really how practical it'd be for a couple
of lines for this. When coding a site however, I never use inline
styles.. CSS all the way (along with XHTML) and validated naturally =)

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/
Jul 17 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.