Home > Software engineering >  pass preg replace variable to function
pass preg replace variable to function

Time:01-15

This is my function:

function bbc2html($content) {
    $search = array (
      '/(\[b\])(.*?)(\[\/b\])/',
      '/(\[u\])(.*?)(\[\/u\])/',
      '/(\[i\])(.*?)(\[\/i\])/',
      '/(\[youtube\])(.*?)(\[\/youtube\])/'
    );
  
    $replace = array (
      '<b>$2</b>',
      '<u>$2</u>',
      '<i>$2</i>',
      '<div  style="width: 25rem;">
       <div  data-source="'.getYoutubeVideoID('$2').'" data-type="youtube">
          <p >As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button"  value="OK">
          <a href="$2" type="button" target="_blank" ><i ></i>direct link</a>
       </div>
       <div  style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
       </div>
       </div>'
    );
    
    return preg_replace($search, $replace , $content);
  }
function getYoutubeVideoID($link):string{
    $baseUrl = parse_url($link, PHP_URL_HOST); 

    if($baseUrl == "youtu.be"){
        $urlParts = explode('/',$link);
        $id = end($urlParts);
    } elseif (preg_match('/(youtube.com)/i',$baseUrl)) {
        if(preg_match('/(youtube.com\/watch\?v=)/i',$link)){
            $urlParts = explode('?v=',$link);
            $id = end($urlParts);
        } elseif(preg_match('/(youtube.com\/)/i',$link)) {
            $urlParts = explode('/',$link);
            $id = end($urlParts);
        } else {
            return "";
        }
    } else {
        return "";
    }

    return $id;
}

I want to pass the variable ($2, contains the link to the youtube video) to the function (getYoutubeVideoID, returns only the id of the video), but it just pass '$2' instead of the link.

Example: [youtube] https://www.youtube.com/watch?v=LXb3EKWsInQ [/youtube]

This should be replaced with:

<div  style="width: 25rem;">
       <div  data-source="LXb3EKWsInQ" data-type="youtube">
          <p >As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button"  value="OK">
          <a href="https://www.youtube.com/watch?v=LXb3EKWsInQ" type="button" target="_blank" ><i ></i>direct link</a>
       </div>
       <div  style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
       </div>
       </div>

CodePudding user response:

The standard preg_replace doesn't allow you to execute a function on the replacement values, you can only pass literals with replacement placeholders.

You can get around this in multiple ways, however preg_replace_callback with that specific case might be the easiest to read. In the following code I also took the liberty of combining your first three shortcodes into a single one that uses a back-reference. I also removed captures that you we're using (for no good reason except to help me debug).

<?php

var_dump(bbc2html('[b]stuff[/b][youtube]abc[/youtube]'));

function getYoutubeVideoID($id)
{
    // Just a demo function
    return '!!'.$id.'!!';
}

function bbc2html($content)
{
    $search = '/\[(b|u|i)]([^\[]*)\[\/\1]/';
    $replace = '<$1>$2</$1>';

    $newContent = preg_replace($search, $replace, $content);

    return preg_replace_callback(
        '/\[youtube](.*?)\[\/youtube]/',
        static function ($matches) {
            return '<div  style="width: 25rem;">
      <div  data-source="'.getYoutubeVideoID($matches[1]).'" data-type="youtube">
          <p >As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button"  value="OK">
          <a href="$2" type="button" target="_blank" ><i ></i>direct link</a>
      </div>
      <div  style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
      </div>
      </div>';
        },
        $newContent
    );
}

Demo: https://3v4l.org/0hkQj

  • Related