0

I hope that someone can help me... I'm not a regex expert and I'm looking for a solution for handle a text substitution.

I have an HTML code like this:

<script>
...something here...
</script>

<script type="text/javascript">
...something here...
</script>

...something here...

<script type="text/javascript">
1st occurrence
...something here...
fbq(...something here...)
...something here...
</script>

...something here...

<script type="text/javascript">
2nd occurrence
...something here...
fbq(...something here...)
</script>

...something here...

I need to find all string between ' that contains the function fbq. So in my example I need to have:

Group1:

<script type="text/javascript">
//1st occurrence
...something here...
fbq(...something here...)
...something here...
</script>

Group2:

<script type="text/javascript">
2nd occurrence
...something here...
fbq(...something here...)
</script>

And so on if there are more occurrences. I think It will be fine also to have more matches instead of more groups.

Consideration: there can be a lot of <script string in my code that doesn't contains 'fbq' function, and I can't be sure how they are positioned and whether in a newline or not.

I've tried many regex code but I cannot find something that works.

I.e. by using

(?:^.*)(<script.*fbq.*<\/script>)(?:.*$)

or

.*(<script.*fbq.*<\/script>).*

I can find only the last occurrence of fbq (in my example only 2nd occurrence).

I've tried also to play with groups inclusion but with no luck.

Then I need to use this regex in a PHP code, for doing a substitution using preg_replace

Any suggestion is very welcome

Thanks in advance!

2
  • 2
    Nonono - use a proper parser (e.g. DOMDocument) instead. Commented May 2, 2020 at 12:57
  • Never used DOMDocument but yes... it seems to be a better solution. I'm looking the docs about that function Commented May 2, 2020 at 13:42

2 Answers 2

2

You must parse HTML, find wanted elements and use regexp for element content. Text search in HTML code (from another sources) is very randomly game. Try DOMDocument and DOMXPath

        $doc = new \DOMDocument;
        $doc->preserveWhiteSpace = 0;
        $doc->strictErrorChecking = 0;
        libxml_use_internal_errors(true);

        $doc->loadHTML($html);

        $xpath = new \DOMXPath($doc);
        // search all script element as nodeList
        $nodeList = $xpath->query('//script');
        foreach ($nodeList as $node) {

            $node->nodeValue = 'Hello, world!'; // or some text changes,
            // but remember that comments are special nodes in DOM
            $node->parentNode->replaceChild($node, $node);
        }

        print $doc->saveHTML();
Sign up to request clarification or add additional context in comments.

6 Comments

You could use something like //script[contains(., "fbq")] to say the script tag must contain the text fbq
@NigelRen thansk, I confirm that it works fine alsow with the contains addition!
@Pavel Musil do you know if it's possible to change also the <script *> tag? i.e. I need that <script> or <script type="text/javascript"> became <script type="text/plain" class="_iub_cs_activate-inline"> (I'm not crazy... it's due to manage cookie consent)
@Fabio - sure, simply use $node->setAttribute('attr_name', 'attr_value');.
If you want create new element, then use $newNode = $doc->createElement('element_name', 'element_text_value'); and with replaceChild put it to dom structure.
|
0

Maybe can be useful for someone in future, this is my final code:

function fix_iubenda_pixelWoocommerce( $buffer ) {
        $doc = new \DOMDocument;
        $doc->preserveWhiteSpace = 0;
        $doc->strictErrorChecking = 0;
        libxml_use_internal_errors(true);

        $doc->loadHTML($buffer);

        $xpath = new \DOMXPath($doc);
        $nodeList = $xpath->query('//script[contains(., "fbq(")]');
        foreach ($nodeList as $node) {
                $node->nodeValue = $node->nodeValue ;
                $node->setAttribute('type', 'text/plain');
                $node->setAttribute('class', '_iub_cs_activate-inline');
        }

        $buffer = $doc->saveHTML();
        return $buffer;
}

Thanks again to Pavel and Nigel for helping me!

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.