Jump to content

matching every 3rd instance and returning full output


jmtz33

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.

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.