Hi,
This is not "only one regex", but it should do the work, considering your input string is in $str
:
$lines = explode(PHP_EOL, $str);
$linesToKeep = array();
foreach ($lines as $line) {
if (!preg_match('#</?(' . $blockTags . ')>#', $line)) {
$linesToKeep[] = $line;
}
}
// Et voila ;-)
$strOK = implode(PHP_EOL, $linesToKeep);
var_dump($strOK);
In a few words :
- It explodes the string to work on line (as you want to keep or reject line by line).
- it loops line by line
- if the line doesn't contain
<TAG>
or </TAG>
, it is put in the $linesToKeep
array
- in the end, the ouput string is built from what's in that array
Maybe there are shorter ways to do, though... But that one is easy enough to understand, I guess (not some kinda "regex hell" or whatever that noone would be able to maintain ^^ )
Edit : As I was re-reading the OP, I noticed the last line was excluded, while it's not with my code... If you want to exclude a line with an opening tag, and the one just after it, here's another proposition :
$lines = explode(PHP_EOL, $str);
$linesToKeep = array();
$i = 0;
$numLines = count($lines);
for ($i=0 ; $i<$numLines ; $i++) {
$line = $lines[$i];
if (!preg_match('#</?(' . $blockTags . ')>#', $line)) {
$linesToKeep[] = $line;
} else {
if (preg_match('#<(' . $blockTags . ')>#', $line)) {
// Opening tag, skip next line too ?
$i++;
}
}
}
$strOK = implode(PHP_EOL, $linesToKeep);
var_dump($strOK);
And if you want to skip lines until the closing tag, you can do that where I put $i++
-- but it's becoming to become harder to read / understand ^^ (And "parsing" HTML by-hand might not be such a good idea, if you want to get to something complicated ^^ )