Jump to content

Recommended Posts

Hi,

 

I'm having a bit of bother doing a bit of string manipulation. I have the following HTML in a variable called $data

<div class="text">
<mofish id="testing" type="testing" title="true" />
</div>

I'm trying to replace the <mofish id="text" type="text" title="true" /> part with a value, for example the word "Hello".

 

However, I dont want to have to hard code into the string replace the attribute values, as these could potentially change. Ideally I would like it to do a string replace on the start of the <mofish tag until the closing tag /> without taking into consideration any of the attributes. I have tried using str_replace but think i'm maybe off tangent? Would this be a regex job? Any guidance much appriciated.

 

Thanks,

 

MoFish

Link to comment
https://forums.phpfreaks.com/topic/297771-find-and-remove-bit-of-string/
Share on other sites

like this?

$str = '<div class="text">
<mofish id="testing" type="testing" title="true" />
</div>';

$replace = 'whatever';

$p1 = strpos($str, '<mofish');
$p2 = strpos($str, '/>', $p1);
$str = substr_replace($str, $replace, $p1+8, $p2-($p1+9));

  • Like 2

You can work this through preg_replace...

$str = '<div class="text">
<mofish id="testing" type="testing" title="true" />
</div>';
 
$pattern = '/<mofish[^>]*>/';
 
$replace = 'whatever';
 
$newString = preg_replace($pattern , $replace , $str);
Edited by akphidelt2007

Hi,

 

Thanks for your replies and appologies in being a bit slow coming back to you.

 

akphidelt2007s answer done exactly as required, as i only required the 'whatever' value to be returned. Thank you!

 

I do however need to amend the pattern slightly, so it only gets mofish tags with specific ids. For example say i only wanted to run the preg_replace where id = 'number2'

$str = '<div class="text">
<mofish id="number1" type="number1" title="true" />
</div>

<div class="text">
<mofish id="number2" type="number2" title="true" />
</div>';

Regards,

 

MoFish

Edited by MoFish

try

$str = '<div class="text">
<mofish id="number1" type="number1" title="true" />
</div>

<div class="text">
<mofish id="number2" type="number2" title="true" />
</div>';

$replace = 'whatever';

$p2=0;
while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
    $p2 = strpos($str, '/>', $p1);
    $x =  (substr($str,$p1,$p2-$p1+2));
    if (strpos($x, 'id="number2"')) {
        break;
    }
}
$newstr = str_replace($x, $replace, $str);

Hi Barand,

 

Found a slight problem.

 

If you put in an ID that doesnt exist, it still does the replace.

 

Is there anyway to just return blank if its not found?

                $str = '<div class="col-xs-3 text-center">
                            <h4><mofish id="number33" type="text" label="Title" /></h4>
                            <p><mofish id="number25" type="text" label="Description" /></p>
                        </div>';

                $replace = 'whatever';

                $p2=0;
                while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
                    $p2 = strpos($str, '/>', $p1);
                    $x =  (substr($str,$p1,$p2-$p1+2));
                    if (strpos($x, 'id="number2"')) {
                        break;
                    }
                }
                $newstr = str_replace($x, $replace, $str);

                echo $newstr;

$p2=0;
$found = 0;
while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
$p2 = strpos($str, '/>', $p1);
$x = (substr($str,$p1,$p2-$p1+2));
if (strpos($x, 'id="number2"')) {
$found = 1;
break;
}
}
if ($found) {
$newstr = str_replace($x, $replace, $str);
}


  • Like 1

Hi Barand,

If you don't mind, I have one more issue I have come across which relates to the code you helped me with.

This if probably something simple I've done, however would appreciate it if you could lend a helping hand, as have been looking at it for a while now.

I have amended the code so that results are coming from a database which seems to be working good to a certain degree...

However the results I am getting back are not quite as I expected. Please see the example below:

<?php

public function run (){

    $str = '<div class="col-xs-3 text-center">
                <h4><mofish id="template1" type="text" label="Title" /></h4>
                <p><mofish id="template2" type="text" label="Description" /></p>
            </div>';
            
    // for each row in database
    foreach($result as $row){

        // set replacement to be the string from db
        $replace = $row['string'];
        $p2=0;
        $found = 0;
        while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
            $p2 = strpos($str, '/>', $p1);
            $x =  (substr($str,$p1,$p2-$p1+2));
            // template contains template1 or template2
            if (strpos($x, 'id="'.$row['template'].'"')) {
                $found = 1;
                break;
            }
        }
        if ($found) {
            $newstr = str_replace($x, $replace, $str);
        }
        
        // i think i need to concatenate these somehow
        echo $newstr;
        // return $newstr;

    }

}

?>

I am getting results returning to the browser, however it seems to be taking it in turns for each instance. I had hoped it would have done both replacements in each instance.

<div class="col-xs-3 text-center">
    <h4>PHP Freaks</h4>
    <p><mofish id="template2" type="text" label="Description" /></p>
</div>

<div class="col-xs-3 text-center">
    <h4><mofish id="template1" type="text" label="Title" /></h4>
    <p>This is a question</p>
</div>

Expected
 

<div class="col-xs-3 text-center">
    <h4>PHP Freaks</h4>
    <p>This is a question</p>
</div>

<div class="col-xs-3 text-center">
    <h4>Another One</h4>
    <p>This is a question</p>
</div>

It is probably something to do with the way I'm echoing them, and possibly need to be concatenating the results together then returning it as one string? Would that be correct?

 

Hope this makes sense,

 

MoFish

try putting the replacement code in a separate function then call it for each row

    // array to simulate db results
    $result =   [
                    ['string'=>'replacement 1', 'template'=>'template1'],
                    ['string'=>'replacement 2', 'template'=>'template2'],
                ];

    $str = '<div class="col-xs-3 text-center">
                <h4><mofish id="template1" type="text" label="Title" /></h4>
                <p><mofish id="template2" type="text" label="Description" /></p>
            </div>';
            
    // for each row in database
    foreach($result as $row){

        // set replacement to be the string from db
        $replace = $row['string'];
        $srch = $row['template'];
        
        $str = replace_mofish($srch, $replace, $str);

    }

echo '<pre>',htmlentities($str),'</pre>';  // check output

function replace_mofish($srch, $replace, $str)
{
        $p2=0;
        $found = 0;
        while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
            $p2 = strpos($str, '/>', $p1);
            $x =  (substr($str,$p1,$p2-$p1+2));
            // template contains template1 or template2
            if (strpos($x, "id=\"$srch\"")) {
                $found = 1;
                break;
            }
        }
        if ($found) {
            return str_replace($x, $replace, $str);
        }
        else return $str;  
}

gives

<div class="col-xs-3 text-center">
                <h4>replacement 1</h4>
                <p>replacement 2</p>
            </div>

Hi Barand,

 

I managed to get your code working, however my $result array from the database returns slightly differently than your example.

 

Mine has keys, which i think is breaking things slightly. ::)

Array
(
    [0] => Array
        (
            [blah] => 41
        )

    [1] => Array
        (
            [blah] => 42
        )

)

All arrays have keys

$result =   [
                    ['string'=>'replacement 1', 'template'=>'template1'],
                    ['string'=>'replacement 2', 'template'=>'template2'],
                ];
                
echo '<pre>',print_r($result, true),'</pre>';

gives

Array
(
    [0] => Array
        (
            [string] => replacement 1
            [template] => template1
        )

    [1] => Array
        (
            [string] => replacement 2
            [template] => template2
        )

)

HI Barand,

 

When used your example code, both replacements worked well. Once changing to the DB it only seems to be doing one for some reason.

<div class="col-xs-3 text-center">	<h4><mofish id="title" type="text" label="Title" /></h4>	<p>Once upon a time...</p></div>

Below is the two functions you helped with. I've amended things slightly but not to drastically.

    public function area($name){

            $query = "SELECT areas_content.*, areas.* FROM areas_content INNER JOIN areas ON areas.id = areas_content.area_id WHERE area_id = '41' ";
            $this->database->sql($query);
            $result = $this->database->getResult(); 

            echo "<pre>";
            print_r($result); 
            echo "</pre>";

            foreach($result as $row){

                // set replacement to be the string from db
                $str = file_get_contents("templates/staff.html", true);
                $replace = $row['content'];
                $srch = $row['location'];
                
                $str = $this->replace($srch, $replace, $str);

            }

            echo '<pre>',htmlentities($str),'</pre>';  // check output

    }
    public function replace($srch, $replace, $str)
    {
            $p2=0;
            $found = 0;
            while(($p1 = strpos($str, '<mofish', $p2)) !== false) {
                $p2 = strpos($str, '/>', $p1);
                $x =  (substr($str,$p1,$p2-$p1+2));
                // template contains template1 or template2
                if (strpos($x, "id=\"$srch\"")) {
                    $found = 1;
                    break;
                }
            }
            if ($found) {
                return str_replace($x, $replace, $str);
            }
            else return $str;  
    }

And the array output

Array
(
    [0] => Array
        (
            [id] => 41
            [content] => Hello world
            [area_id] => 41
            [location] => title
            [name] => Staff
            [template] => staff
            

 => Home
        )

    [1] => Array
        (
            [id] => 41
            [content] => Once upon a time...
            [area_id] => 41
            [location] => description
            [name] => Staff
            [template] => staff
            

 => Home
        )

)

And inside staff.html

<div class="col-xs-3 text-center">
	<h4><mofish id="title" type="text" label="Title" /></h4>
	<p><mofish id="description" type="text" label="Description" /></p>
</div>

Morning Barand,

 

You are correct in that moving the get file contents outside of the loop resolved the populating of data.

 

I moved it inside the loop  as wanted to get the location from the DB from the 'template' field, like the following.

foreach($result as $row){
$str = file_get_contents("templates/".$row['template'].".html", true);

I'm assuming from your response above, this technique would not work?

 

Thanks.

Edited by MoFish

 

$str = file_get_contents("templates/".$row['template'].".html", true);

 

That is not what the code you posted shows. We cannot help with your code if you post something different from what you are really doing.

You need to save the changes so you do not reset the input each time

foreach($result as $row){

                // set replacement to be the string from db
                $str = file_get_contents("templates/staff.html", true);
                $replace = $row['content'];
                $srch = $row['location'];
                
                $str = $this->replace($srch, $replace, $str);

                file_put_contents("templates/staff.html", $str);         // ADD
            }

An alternative would be only to get the file contents when there is a new id value

$prevID = '';
foreach($result as $row){

                // set replacement to be the string from db
                if ($row['id'] != $prevID {
                    $str = file_get_contents("templates/staff.html", true);
                    $prevID = $row['id'];
                }
                $replace = $row['content'];
                $srch = $row['location'];
                
                $str = $this->replace($srch, $replace, $str);

            }
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.