Jump to content

matching every 3rd instance and returning full output


Recommended Posts

I am having some trouble as this works great in the Regexr program at http://gskinner.com/RegExr/ but not through my php code. The $theData is a file I have opened and I want to replace every 3rd instance of the <p> tag with something else.

 

This works fine but it returns only the matched and changed lines rather than the entire document. I am basically using this as a sed/awk for replacing information on a file but I don't know how to get the full output so that I can write it back to the file. Any suggestions or at least a keyword of what to research to do this. Thanks!

 

 

echo preg_replace('/<p>.*?(?<!\A)<p>/sm', '<p style="float:left;">', $theData);

 

Something as complex as this is going to be hard for RegEx to handle alone.

My advice is to use a combination of PHP and RegEx, as it will probably much faster.

 

May I see some sample data to help build a working example?

Here's a quick example I put together

 

<?php 

$data = '<p>something</p> BUNCH OF OTHER STUFF TO IGNORE
<p>something else</p> BLAH BALH BLAH
<p>LELELELE</p>MORE GARBAGE <p>hello world</p>
aryarharhar <p> another paragraph</p> aghaerhaerha
<p> and more </p> BUNCH OF OTHER STUFF TO IGNORE
<p>something else</p> BLAH BALH BLAH
<p>LELELELE</p>MORE GARBAGE <p>hello world</p>
aryarharhar <p> another paragraph</p> aghaerhaerha
<p> and more </p> ahrahearhae';

// Match every single <p> tag along with offset
preg_match_all( '/<p>/', $data, $ps, PREG_SET_ORDER | PREG_OFFSET_CAPTURE );
// This will count how many iterations we've done, so we know when we've hit the 3rd <p>
$i = 1;
// This will track any changes we make to the string, so we can update our offsets accordingly
$offset = 0;
// Loop through our results
foreach( $ps as $p ) {
// Check if $i / 3 has a 0 remainder, if so, it's a 3rd <p>
if( ($i % 3) == 0  ) {
	// Rebuild the $data string, grab everything up to the current <p> followed by our new <p>
	$data = substr($data,0,$p[0][1]+$offset) . '<p style="float:left;">' . 
		// Followed by everything after the <p>. We use 3 becuase that's how many characters
		// we need to skip (<p>)
		substr($data,$p[0][1]+3+$offset);
	// Increase the offset by 20, because we have just made $data 20 characters longer by taking
	// out <p> and adding <p style="float:left;">
	$offset += 20;
}
// Increase our iterations by 1
$i++;
}

echo nl2br(htmlspecialchars($data));

?>

Here's an alternative without using RegEx

 

<?php 

$data = '<p>something</p> BUNCH OF OTHER STUFF TO IGNORE
<p>something else</p> BLAH BALH BLAH
<p>LELELELE</p>MORE GARBAGE <p>hello world</p>
aryarharhar <p> another paragraph</p> aghaerhaerha
<p> and more </p> BUNCH OF OTHER STUFF TO IGNORE
<p>something else</p> BLAH BALH BLAH
<p>LELELELE</p>MORE GARBAGE <p>hello world</p>
aryarharhar <p> another paragraph</p> aghaerhaerha
<p> and more </p> ahrahearhae';

$i = 1;
$offset = 0;
while( ($offset = strpos($data,'<p>',$offset)) !== FALSE ) {
if( $i % 3 == 0 ) {
	$data = substr($data,0,$offset) . '<p style="float:left;">' .
		substr($data,$offset+3);
}
$i++;
$offset++;
}

echo nl2br(htmlspecialchars($data));

?>

 

This one can't be modified to accept variations of the <p> tag though, while the RegEx one can.

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.