views:

39

answers:

2

I just can't figure this out, for some reason this:

$string = "#mainparent {
position: relative;
top: 100px;
left: 100px;
width:4994px;
}";

$elementwidth = "88";

  $re1='(.*?)'; # Non-greedy match on filler
  $re2='(mainparent)';  # Word 1
  $re3='(.*)';  # Non-greedy match on filler
  $re4='(width:)';
  $re5='(.*)';  # Word 2
  $re6='(;)';   # Any Single Character 1
$pattern="/".$re1.$re2.$re3.$re4.$re5.$re6."/s";
    $replacement= '$1'.'$2'.'$3'. '$4'. $element_width .'$6';
    $return_string = preg_replace_component ($string, $pattern, $replacement );
     #c}

     echo $return_string; return;

output this (below), I can't understand why it is replacing the "width:" based on the way I have set it up.. any advice is appreciated

#mainparent { position: relative; top: 100px; left: 100px; 88; } 
+5  A: 

The problem is that your replacement string looks like this:

'$1$2$3$488$6'
       ^^^

Because the character immediately following the group number is a digit, it is being interpreted as group 48 instead of group 4.

See the preg_replace manual "Example #1 Using backreferences followed by numeric literals". The smallest change required to make it work is to surround the 4 by curly braces so that it is separated from the 88.

$replacement = '$1' . '$2' . '$3'. '${4}'. $element_width . '$6';

But this isn't a good way to do it and there are also a number of issues with your code.

  • Regular expressions are not really suitable for parsing and modifying CSS.
  • First you write $elementwidth and later you write $element_width.
  • It's not necessary to create 6 different groups if you only intend to replace one of them.
Mark Byers
Not to mention he used "88" instead of "88px". Also, why was this downvoted?
animuson
Hey Rick, this is the correct answer.
editor
its from a regex generator which is why its in the 6 groups, yes I made an error with the $element_Width name in copying it over to this post so that wasn't the issue... as far as the "88" instead of "88px", that has no bearing on this, I'm just testing this out.. why would that matter for replacing '(.*)' ?
Rick
as far as CSS not being ideal for this.. well yeah I understand that but its more just trying to figure out this for other uses too.. I hadn't realized aobut the brackets, thanks for the info on that
Rick
@Rick: Actually maybe I could word that differently... it's the regular expression that I think is not a good idea.
Mark Byers
what would you suggest to use instead? I'm not just going to use this for css so is there something else I should look into for general use? thanks for any advice.. as far as why I'm doing this in the first place, its since I am generating values for the width / height based off values input from jquery, I need a height / width for every value, including hundreds of images, for which I haven't set the image height / width in css (but jquery can get it for me from just the image), which is why I'm doing it this way, kind of a dirty method but figured it was the quickest
Rick
According to [the PHP manual](http://jp.php.net/manual/en/function.preg-replace.php), `$488` would be interpreted as `$48` followed by `8`, not the single back reference `$488`. Back when I worked with Perl, back references only went up to `$9`, so I wanted to look this up. They provided the alterate syntax, `${4}` to remove this ambiguity, I think.
Andrew
@Andrew: You are correct. Thanks for the fix.
Mark Byers
A: 

Here's a little function I wrote that changes arbitrary properties:

function css_replace($selector, $property, $new_value, $string) {
    $pattern = '~(' . $selector . '\s*{.*?' . $property . '\s*:\s*)([^;]+)(;)~s';
    return preg_replace($pattern, '${1}' . $new_value . '${3}', $string);
}

This:

$string = "#mainparent {
position: relative;
top: 100px;
left: 100px;
width:4994px;
}";

echo css_replace('#mainparent', 'width', '300px', $string);

Prints:

#mainparent {
position: relative;
top: 100px;
left: 100px;
width:300px;
}

WARNING: This is the result of 5 minutes of work. Behavior not thoroughly tested.

NullUserException