Forum Moderators: coopster

Message Too Old, No Replies

Complicated (?) regex for preg replace()

         

Duijst

11:04 am on Apr 2, 2009 (gmt 0)

10+ Year Member



Hi there! Just started to learn something about regular expressions. I spent two days searching this forum and other resources to solve the following problem.

These variables are given:

$extra which may contain:

A) [b]''[/b] (noting)
B) [b]'style="foo:bar;"'[/b] (style tag)
C) [b]'tag="something"'[/b] (one or more other tags)
D) [b]'tag="something" style="foo:bar;"'[/b] (both style and other tags, not necessary in that order)

[b]$width[/b] which may contain:
1) [b]123[/b] (any integer, if no unit it should be 'px')
2) [b]'456em'[/b] (any integer with any unit)
No check is needed on the integer.

I am convinced that somewhere in this world there must exist a regexp for preg_replace() that adds the width to $extra like this:

A1) [b]'style="width:123px;"'[/b] ($extra A + $width 1)
A2) [b]'style="width:456em;"'[/b] ($extra A + $width 2)
B1) [b]'style="width:123px; foo:bar;"'[/b] ($extra B + $width 1)
B2) [b]'style="width:456em; foo:bar;"'[/b] ($extra B + $width 2)
C1) [b]'style="width:123px;" tag="something"'[/b] ($extra C + $width 1)
C2) [b]'style="width:456em;" tag="something"'[/b] ($extra C + $width 2)
D1) [b]'tag="something" style="width:123px; foo:bar;"'[/b] ($extra D + $width 1)
D2) [b]'tag="something" style="width:456em; foo:bar;"'[/b] ($extra D + $width 2)

But I can't figure it out. Or is there a better solution? Please enlighten me, thank you.

Cheers,
Henk-Sjoerd.

(edit: typos)

[edited by: Duijst at 11:53 am (utc) on April 2, 2009]

astupidname

1:37 pm on Apr 2, 2009 (gmt 0)

10+ Year Member



While not being a 'one regEx' solution, does this get you closer to what you want?

<?php
function buildAttributes($extra,$width) {
$rex = '/"$/'; //just a pattern to remove the last double-quote in string
$rex2 = '/^[0-9]+%¦in¦cm¦mm¦em¦ex¦pt¦pc¦px$/'; //looking for all the possible css units after a digit/set of digits
if (!preg_match($rex2,$width)) { //if no css unit after number/s in $width
$width = $width.'px';
}
echo preg_replace($rex," width:$width;\"",$extra);
}

buildAttributes('style="foo:bar;"','456em');
echo '<br>';
buildAttributes('tag="something" style="foo:bar;"',123);
?>

Note you will need to replace the regEx 'or' ( ¦ ) (single pipe) conditionals in $rex2 as this forum stupidly wrecks them by replacing them with wrong html entity code.

Duijst

2:28 pm on Apr 2, 2009 (gmt 0)

10+ Year Member



Hi Astupidname,

Looks good! It gets me closer. It doesn't do the full job yet, but I'll first try to understand what's happening so I can describe the remaining problem better.

Ofcourse it might be ambtious to get things done in one regex. But it must be possible to be more elegant then this:


function addWidth($extra, $w) {
$w = empty($w) ? $this->size['w'] . 'px;' : $w . 'px;';
$s = 'width: ' . $w;
if (empty($extra)) {
$extra = 'style="'.$w.'"';
} else {
if (strstr($extra, 'style="')) {
$extra = str_replace('style="', 'style="'.$w.' ', $extra);
} else {
$extra = 'style="'.$w.'" ' . $extra;
}
}
return($extra);
}

.... which even doesn't consider an existing unit in $width (yet).

Well, I'll do my homework first.

Thanks!
Henk-Sjoerd.

Duijst

7:56 pm on Apr 2, 2009 (gmt 0)

10+ Year Member



Got it! With slight modification:

function buildAttributes($extra, $width) {
. $rex = '/style="/'; // just a pattern to find the style tag anywhere in string
. $rex2 = '/^[0-9]+%¦in¦cm¦mm¦em¦ex¦pt¦pc¦px$/'; // looking for all the possible css units after a digit/set of digits
. if (!preg_match($rex2,$width)) { // if no css unit after number/s in $width
. . $width = $width.'px';
. }
. if (preg_match($rex,$extra)) { // if style tag present extend it
. . $extra = preg_replace($rex, 'style="width:'.$width.'; ', $extra);
. } else { // else create it
. . $extra .= ' style="width:'.$width.'"';
. }
. echo $extra;
}

This means that all variants work:

With style tag anywhere:
buildAttributes('style="foo:bar;"','456em');
buildAttributes('style="foo:bar;" tag="something"',123);
buildAttributes('tag="something" style="foo:bar;" onMouseOver="blabla"',123)

Without style tag:
buildAttributes('tag="something"',123);
buildAttributes('','50%');

Again something learned about regular expressions. Thanks!

Cheers,
Henk-Sjoerd.

[edited by: Duijst at 8:01 pm (utc) on April 2, 2009]

astupidname

11:14 pm on Apr 2, 2009 (gmt 0)

10+ Year Member



Nice! Congrats and by the way, welcome to webmasterworld! See ya around!