I've tried this a number of different ways and I've even downloaded the Regular Expression reference sheet from addedbytes.com, but I just can't figure out how to move this eregi_replace() statement into a preg_replace() statement.

I've read and understood the delimiter requirements for preg_replace(), but I think the problem is the modifiers. How to I know which modifier to use for this function? I've tried \A, \b, and \e, but none seem to work. I think there's something simply I'm missing.

$bodytag = '%%BODY%%';
$header = eregi_replace($bodytag . '.*', '', $temp);
$footer = eregi_replace('.*' . $bodytag, '', $temp);

I've tried the following:

$header = preg_replace('/%%BODY%%.*/i', '', $temp);
$footer = preg_replace('/.*%%BODY%%/i', '', $temp);

But it doesn't seem to work. What am I missing?

More recently, I've tried this with no fix.

$bodytag = "%%BODY%%";
$header = preg_replace("/".$bodytag."(.*)/i", '', $temp);
$footer = preg_replace("/(.*)".$bodytag."/i", '', $temp);

Dani AI

Generated

Short summary: the symptom (double headers/footers) came from pattern matching not spanning newlines. As pointed out, PCRE's dot (.) does not match newlines by default — add the "s" modifier or use a different approach so the placeholder match can cross line breaks. The modifiers after the closing delimiter can be combined (for example, case-insensitive plus dot-all), and that is the correct way to reproduce eregi_replace behavior with preg_replace.

A few practical tips and pitfalls:

  • Escape the placeholder if it may contain regex metacharacters (use a quoting function) so the split is safe.
  • If the template can contain multiple placeholders and you only want the first split, limit the split to two pieces instead of using a greedy pattern that could span to a later marker.
  • For simple templates a string split by the literal token is fastest; for robust code use a regex split with a limit.

Example (safe, avoids the greedy ".*" problem and handles newlines):

$bodytag = '%%BODY%%';
$parts = preg_split('/' . preg_quote($bodytag, '/') . '/s', $temp, 2);
$header = $parts[0];
$footer = isset($parts[1]) ? $parts[1] : '';

If you prefer a single-regex capture, match the two halves with anchors and the dot-all flag so captures include newlines. Also note performance: plain string functions (strpos/explode/substr) are simpler and faster for small templates; regex is more flexible. Finally, avoid the old ereg/eregi family — they were deprecated and removed in later PHP releases, so preg_* is the forward-compatible choice.

Recommended Answers

All 4 Replies

Can you please give an input and output example of what you are trying to achieve ? That may make it easier for us to come up with a solution.

I wish it were that simple.....

The code parses a page template, replacing the "%%BODY%%" marker in the template with the actual page body. The page body is dictated by the URL the user is currently at.

The current problem is that all attempts that I've made it causes double header's (the top of the page is displayed twice) and double footers (the bottom of the page is displayed twice).

To be honest, I'm not looking for someone to give me the answer, just trying to get some help on finding out how "preg_replace()" works and in what ways is it different.

The full section of code for this, however, is:

<?php
if (!defined('ISINC')) die('serious error! File: '.__FILE__.' File line: '.__LINE__.'');
if (!empty($site_title)) $title = $site_title;
if (!empty($titles[$inc])) $title = $title . ": $titles[$inc]";
$themepage = $theme_dir . 'theme.php';
$bodytag = '%%BODY%%';
if (file_exists($themepage)) {
    ob_start();
    include_once $themepage;
    $temp = ob_get_contents();
    ob_end_clean();
    if (isset($image_dir)) {
        $temp = preg_replace('/(<img src=")(images\/)/is', '$1' . $image_dir, $temp);
        $temp = preg_replace('/(background=")(images\/)/is', '$1' . $image_dir, $temp);
    }   
    if (isset($theme_dir)) $temp = preg_replace('/( href=")([^>]*?eticket\.css")/is', '$1' . $theme_dir . '$2', $temp);
    if (isset($page)) $temp = str_replace('admin.php', $page, $temp);
    if (isset($page)) $temp = str_replace('index.php', $page, $temp);
    $header = eregi_replace($bodytag . '.*', '', $temp);
    $footer = eregi_replace('.*' . $bodytag, '', $temp);
    //$header = preg_replace("/".$bodytag."(.*)/i", '', $temp);
    //$footer = preg_replace("/(.*)".$bodytag."/i", '', $temp);
}
if (!empty($header)) {
    echo $header;
    unset($header);
}
?>

By default PCRE regex patterns in PHP don't match newlines with . and maybe POSIX patterns do, I'm not sure.
But since you probably have newlines in your template file, I think changing the pattern to the following should solve your issues:

$header = preg_replace("/".$bodytag."(.*)/is", '', $temp);
$footer = preg_replace("/(.*)".$bodytag."/is", '', $temp);

Also there is probably an easier way to do this, without the need for regex, assuming I have the right idea of how your template file works.

$bodypos = strpos($temp, $bodytag);                   // Find the position of the %BODY%
$header = substr($temp, 0, $bodypos);                 // The length of the header is the same as the position of the %BODY%
$footer = substr($temp, $bodypos + strlen($bodytag)); // And the start of the footer is the position of the %BODY% plus it's length

Thanks Insensus!

Your preg_replace() statements actually work! So, it was just the "s" that was missing on the modifiers.

I knew that it had to be something simple like that, not to mention the fact that the preg_replace() documents on the PHP site (listed here) don't indicate that the modifiers can be stacked like that.

Thanks again!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.