1

I need to hide all "p" tags in a HTML file that have an inline style with a "left" offset of 400 or more.

I'm hoping some clever regex will replace "left:XXX" with "display:none" should "xxx" be 400 or more.

For example, this:

<p style="position:absolute;top:98px;left:472px;white-space:nowrap">

...would need to be replaced with this:

<p style="position:absolute;top:98px;display:none;white-space:nowrap">

It seems simple enough logic, but the regex and PHP is mind boggling for me.

Here is what I've been trying to do, but I can only get it to work line-by-line:

$width = preg_match("left:(.*?)px",$contents);
if ($width >399)
{
    $contents = preg_replace('/left:(.*?)px/', "display:none", $contents);
}

Any suggestions greatly appreciated! :)

Wonko

6
  • What do you want exactly ?! Do you want to replace line2 instead line1 ? Commented May 15, 2015 at 22:23
  • Good question Fatemeh, thanks for asking. I need to replace "left:xxx" with "display:none" if "xxx" is greater than 400. Commented May 15, 2015 at 22:26
  • @WonkotheSane Sorry, but Stack Overflow is not a code writing service. You need to first write code that shows a significant attempt to solve the problem and show any research you did. You also need to explain in detail what the problem with the current code is so that it can be clearer to those answering. You can read all about it on the how to ask guide page. If you want code to simply be written for you, I suggest you instead hire a freelance programmer. Commented May 15, 2015 at 22:31
  • Now, you say greater than 400, and before it was offset of 400 or more. What is the exact requirement? Commented May 15, 2015 at 22:33
  • @WonkotheSane: You can use this regex: $re = "/<p\\s+[^<]*style=\"[^\"]*left:\\K(?:[4-9][0-9][0-9]|[1-9][0-9][0-9][0-9])px/i"; (to be replaced with display:none). I am not posting, since most probably this question is going to be closed by "xeger"-people. Commented May 15, 2015 at 22:39

2 Answers 2

2

Don't believe that regex will solve all the problem of the world:

Use DOMDocument to extract the p tags with a style attribute, extract the "left" value with a regex pattern from the style attribute and then proceed to the replacement when the "left" value is greater or equal to 400 (test this with a simple comparison).

$dom = new DOMDocument;
$dom->loadHTML($html);

$pTags = $dom->getElementsByTagName('p');

foreach($pTags as $pTag) {
    if ($pTag->hasAttribute('style')) {
        $style = $pTag->getAttribute('style');
        $style = preg_replace_callback(
            '~(?<=[\s;]|^)left\s*:\s*(\d+)\s*px\s*(?:;|$)~i',
            function ($m) {
                return ($m[1] > 399) ? 'display:none;' : $m[0];
            },
            $style
        );
        $pTag->setAttribute('style', $style);
    }
}

$result = $dom->saveHTML();

EDIT: in the worst scenario, the style attribute may contain display:block; or display with a value other than none after the left value. To avoid any problem, it is better to put display:none at the end.

$style = preg_replace_callback(
    '~(?<=[\s;]|^)left\s*:\s*(\d+)\s*px\s*(;.*|$)~i',
    function ($m) {
        return ($m[1] > 399) ? $m[2]. 'display:none;' : $m[0];
    },
    $style
);
Sign up to request clarification or add additional context in comments.

13 Comments

Woah, it works perfectly. I would never have thought of DOMDocument. Thanks for putting me on the right track, you rock!
I can't understand what is $m ?
@Fatemeh: $m is the match array, index 0 is the whole match and other indexes are capture groups (1 for the first, 2 for the second, etc.)
aha, but $m[1] means one error was found in the matching ?
@Fatemeh: No, $m[1] is the content captured between these parenthesis in the pattern: (\d+) (so it is the value of the "left" parameter, the number).
|
1

I've tested it and it works correctly:

$string = '<p style="position:absolute;top:98px;left:472px;white-space:nowrap">';

 $test = str_replace('left:', 'display:none;[', $string );
 $test = str_replace('white-space', ']white-space', $test );
 $out = delete_all_between('[', ']', $test);
 print($out); // output

function delete_all_between($beginning, $end, $string) {
  $beginningPos = strpos($string, $beginning);
  $endPos = strpos($string, $end);
  if ($beginningPos === false || $endPos === false) {
    return $string;
  }

  $textToDelete = substr($string, $beginningPos, ($endPos + strlen($end)) - $beginningPos);

  return str_replace($textToDelete, '', $string);
}

output:

<p style="position:absolute;top:98px;display:none;white-space:nowrap">

enjoy it ... !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.