1

I have these imaginary strings:

$txts=
  array('<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>',
        '<script>document.getElementById("demo").innerHTML = "Hello JavaScript!";</script>',
        'document.getElementById("demo").innerHTML = "Hello JavaScript!";');

Now I would like an elegant simple solution to check if the <script> and </script> tags are surrounding the string and if not, surround the string with those tags. So, $txts[0] and $txts[1] are valid but $txt[2] should be surrounded with <script> </script>

I have a couple of solutions in my head but none 'sits' right with me, they are over complex or not clean.

Can you come up with a proper solution?

3
  • 1
    use the DOM luke Commented Dec 29, 2015 at 15:47
  • I think that would make it even more complex. The source of the string is an input box on a form that gets posted. I just need to know did they include the script tags, if not, add them. Thanks for suggesting it! Commented Dec 29, 2015 at 15:54
  • It's the only really sane way. And not sure why it would be complex... Everythign else will break in glorious ways. Commented Dec 29, 2015 at 17:41

3 Answers 3

1

Does it have to be a regex solution? Loops over the array and repairs it if necessary. Ensures that you have an array with open and closing tags in the end.

<?php
$txts=
  array('<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>',
        '<script>document.getElementById("demo").innerHTML = "Hello JavaScript!";</script>',
        'document.getElementById("demo").innerHTML = "Hello JavaScript!";');

$opentag = "<script";
$closingtag = "</script>";
for ($i=0;$i<count($txts);$i++) {
    if (strpos($txts[$i], $opentag) === false) $txts[$i] = $opentag.">".$txts[$i];
    if (substr($txts[$i], -(strlen($closingtag))) !== $closingtag) $txts[$i] .= $closingtag;
}
print_r($txts); // all entries have open and closing tags in the end
?>
Sign up to request clarification or add additional context in comments.

Comments

0

Check each array element:

foreach($txts as $txt) {
        return is_int(strpos($txt, '<script')) && is_int(strpos($txt, '</script>')));
}

Or via a function:

function checkTags($beggining, $ending, $string)
{
     return is_int(strpos($string, $beggining)) && is_int(strpos($string, $ending)))
}

Calling function for each element

foreach($txts as $txt) {
   if(!checkTags('<script','</script>', $txt)) {
       //treat error case
   }
}

Note: is_int is used because the substring might be at possition 0 (the beginning as in your case) and evaluates as false.

Comments

0

/^<script[^<]*>/ makes sure the opening tag is complete

/<\/script>$/ makes sure the closing tag is there

I would do it this way:

$txts = array(
    '<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>',
    '<script>document.getElementById("demo").innerHTML = "Hello JavaScript!";</script>',
    'document.getElementById("demo").innerHTML = "Hello JavaScript!";'
);

foreach ($txts as &$txt) {
    if (!preg_match('/^<script[^<]*>/', $txt)) {
        $txt = '<script>' . $txt;
    }

    if (!preg_match('/<\/script>$/', $txt)) {
        $txt = $txt . '</script>';
    }
}

var_dump($txts);

Output:

array(3) {
  [0]=>
  string(66) "<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>"
  [1]=>
  string(81) "<script>document.getElementById("demo").innerHTML = "Hello JavaScript!";</script>"
  [2]=>
  &string(81) "<script>document.getElementById("demo").innerHTML = "Hello JavaScript!";</script>"
}

2 Comments

Can't see why it isn't useful as it does exactly what was asked "check if the [..] tags are surrounding the string and if not, surround the string with those tags"
I don't understand the downvote either. Your solution looks best to me.

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.