Link to home
Start Free TrialLog in
Avatar of justravis
justravis

asked on

Regular Expressions & preg_replace()

I see that ^ and $ are included in most expressions.  Should you include them if the search string may not be at the beginning or end of the line and you are not sure how many characters will be before or after it?

For example, I want an expression that will use preg_replace() to cycle through html docs and change all the body tags (including attributes) to a comment (<!-- body variable begins here -->).

My concern is that there will be important code before or after the body tag that I want unchanged.  It is impossible to plan on the number of characters of this code, so should I use ^ and $?  Or should I just start and end the expression with /?

My code thus far is:
[php]<?php
$text = preg_replace("/^(<body+)(.*)>+$/", "<!-- body variable begins here -->", $text)
?>[/php]

It just deletes the body tag.  The comment is not inserted.  What am I doing wrong?

I added ^ and $, but the result was the same.
Avatar of Big_Red_Dog
Big_Red_Dog

Try this:

Add "is", remove +

$text = preg_replace("/^(<body)(.*)>+$/is", "<!-- body variable begins here -->", $text)
Why a regular expression?

You can do:

$html = str_replace('<body', "<!-- body variable begins here -->\n<body", $html);

And get it all done.

This however will not work if you've got a whole load of other possibilities OR if tag body can also be in mixed case. There is stri_replace() function in CVS now, but will be only available some time later.

str_replace() is also significally faster than preg_replace.

As of preg, you could do this:

$html = preg_replace("/<body/i", "<\!-- body variable begins here -->\n<body", $html);

Hope this helps
Maxim Maletsky
maxim@php.net
Avatar of justravis

ASKER

Hi Maxim.  I think I hav seen your comments in the manual.

For some reason, I thought str_replace did not support regex.  Only simple replacements.

I want the code to replace the whole body tag including attributes that me be there, so I need regex.

I'll try yr sugestions and answer back today.
Here is what happened when I tried to implement your ideas:
        #Big Red Dog @ Experts-Exchange.com
        #Result: Outputs comment, but replaces body tag as well as all text that follows.
        #$text = preg_replace("/^(<body)(.*)>+$/is", "<!-- body variable begins here -->", $text);

        #S-Maxim (maxim@php.net) @ Experts-Exchange.com
        #Result: Simply outputs comment before body tag.
        #$text = preg_replace("/<body/i", "<\!-- body variable begins here -->\n<body", $text);


Got this working pretty well:
[php]$text = preg_replace("/<(B|b)(O|o)(D|d)(Y|y)(.*)>{1}/", "<!-- body variable begins here --
>", $text);[/php]

Only problem is that it also replaces any other tags immediately following.  I'm thinking it is looking for the last '>' on that line.  Shouldn't '>{1}/' make it stop after first occurrence?  Any ideas?
Found solution, but don't understand why.

[php]$text = preg_replace("/<(B|b)(O|o)(D|d)(Y|y)(.*?)>/", "<!-- body variable begins here -->"
, $text);[/php]

Adding the question mark limited the replace to only the body tag.  It no longer replaces any tags or comments on the same line.  Does anybody know the siginifance of using '*' and '?' together?  To me, the '?' would just override the '*'.

I cut out the {1} after the '>' because it didn't seem to make a difference either way.
ASKER CERTIFIED SOLUTION
Avatar of Big_Red_Dog
Big_Red_Dog

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
So is everything working for you now?
Sorry.  For the delay.  Is it possible to divy up the pioints?  If so, how?
There are two ways:

1) Go to https://www.experts-exchange.com/Community_Support/ and ask them to split the points for https://www.experts-exchange.com/questions/20521028/Regular-Expressions-preg-replace.html however you want.

2) Award these points to one person, and then in your closing comment indicate that you have created another question with the subect of "Points for xxx" where xxx is whoever else you want to give points to, then only accept a reply from that person.
Dear justravis

I've refunded 25 points to enable you to accept the comment of Big_Red_Dog and to post a "Points for <expertname>" Q for the other expert in the same topic area.

Please:
1) Post the link to the original Q in the "Points for <expertname>" and
2) Add in the original Q a comment with the link to the "Points for <expertname>", thus the email notif will warn the expert.

modulo

Community Support Moderator
Experts Exchange
Finalized.

s-maxim points at:
https://www.experts-exchange.com/questions/20570346/Points-for-s-maxim.html

modulo

Community Support Moderator
Experts Exchange