Пример #1
0
/**
 * Process phrases intelligently found within a HTML text (such as adding links).
 *
 * @staticvar array $usedpharses
 * @param string $text             the text that we are filtering
 * @param array $link_array       an array of filterobjects
 * @param array $ignoretagsopen   an array of opening tags that we should ignore while filtering
 * @param array $ignoretagsclose  an array of corresponding closing tags
 * @param bool $overridedefaultignore True to only use tags provided by arguments
 * @return string
 **/
function filter_phrases($text, &$link_array, $ignoretagsopen = NULL, $ignoretagsclose = NULL, $overridedefaultignore = false)
{
    global $CFG;
    static $usedphrases;
    $ignoretags = array();
    // To store all the enclosig tags to be completely ignored.
    $tags = array();
    // To store all the simple tags to be ignored.
    if (!$overridedefaultignore) {
        // A list of open/close tags that we should not replace within
        // Extended to include <script>, <textarea>, <select> and <a> tags
        // Regular expression allows tags with or without attributes
        $filterignoretagsopen = array('<head>', '<nolink>', '<span class="nolink">', '<script(\\s[^>]*?)?>', '<textarea(\\s[^>]*?)?>', '<select(\\s[^>]*?)?>', '<a(\\s[^>]*?)?>');
        $filterignoretagsclose = array('</head>', '</nolink>', '</span>', '</script>', '</textarea>', '</select>', '</a>');
    } else {
        // Set an empty default list.
        $filterignoretagsopen = array();
        $filterignoretagsclose = array();
    }
    // Add the user defined ignore tags to the default list.
    if (is_array($ignoretagsopen)) {
        foreach ($ignoretagsopen as $open) {
            $filterignoretagsopen[] = $open;
        }
        foreach ($ignoretagsclose as $close) {
            $filterignoretagsclose[] = $close;
        }
    }
    // Invalid prefixes and suffixes for the fullmatch searches
    // Every "word" character, but the underscore, is a invalid suffix or prefix.
    // (nice to use this because it includes national characters (accents...) as word characters.
    $filterinvalidprefixes = '([^\\W_])';
    $filterinvalidsuffixes = '([^\\W_])';
    // Double up some magic chars to avoid "accidental matches"
    $text = preg_replace('/([#*%])/', '\\1\\1', $text);
    //Remove everything enclosed by the ignore tags from $text
    filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
    // Remove tags from $text
    filter_save_tags($text, $tags);
    // Time to cycle through each phrase to be linked
    $size = sizeof($link_array);
    for ($n = 0; $n < $size; $n++) {
        $linkobject =& $link_array[$n];
        // Set some defaults if certain properties are missing
        // Properties may be missing if the filterobject class has not been used to construct the object
        if (empty($linkobject->phrase)) {
            continue;
        }
        // Avoid integers < 1000 to be linked. See bug 1446.
        $intcurrent = intval($linkobject->phrase);
        if (!empty($intcurrent) && strval($intcurrent) == $linkobject->phrase && $intcurrent < 1000) {
            continue;
        }
        // All this work has to be done ONLY it it hasn't been done before
        if (!$linkobject->work_calculated) {
            if (!isset($linkobject->hreftagbegin) or !isset($linkobject->hreftagend)) {
                $linkobject->work_hreftagbegin = '<span class="highlight"';
                $linkobject->work_hreftagend = '</span>';
            } else {
                $linkobject->work_hreftagbegin = $linkobject->hreftagbegin;
                $linkobject->work_hreftagend = $linkobject->hreftagend;
            }
            // Double up chars to protect true duplicates
            // be cleared up before returning to the user.
            $linkobject->work_hreftagbegin = preg_replace('/([#*%])/', '\\1\\1', $linkobject->work_hreftagbegin);
            if (empty($linkobject->casesensitive)) {
                $linkobject->work_casesensitive = false;
            } else {
                $linkobject->work_casesensitive = true;
            }
            if (empty($linkobject->fullmatch)) {
                $linkobject->work_fullmatch = false;
            } else {
                $linkobject->work_fullmatch = true;
            }
            // Strip tags out of the phrase
            $linkobject->work_phrase = strip_tags($linkobject->phrase);
            // Double up chars that might cause a false match -- the duplicates will
            // be cleared up before returning to the user.
            $linkobject->work_phrase = preg_replace('/([#*%])/', '\\1\\1', $linkobject->work_phrase);
            // Set the replacement phrase properly
            if ($linkobject->replacementphrase) {
                //We have specified a replacement phrase
                // Strip tags
                $linkobject->work_replacementphrase = strip_tags($linkobject->replacementphrase);
            } else {
                //The replacement is the original phrase as matched below
                $linkobject->work_replacementphrase = '$1';
            }
            // Quote any regular expression characters and the delimiter in the work phrase to be searched
            $linkobject->work_phrase = preg_quote($linkobject->work_phrase, '/');
            // Work calculated
            $linkobject->work_calculated = true;
        }
        // If $CFG->filtermatchoneperpage, avoid previously (request) linked phrases
        if (!empty($CFG->filtermatchoneperpage)) {
            if (!empty($usedphrases) && in_array($linkobject->work_phrase, $usedphrases)) {
                continue;
            }
        }
        // Regular expression modifiers
        $modifiers = $linkobject->work_casesensitive ? 's' : 'isu';
        // works in unicode mode!
        // Do we need to do a fullmatch?
        // If yes then go through and remove any non full matching entries
        if ($linkobject->work_fullmatch) {
            $notfullmatches = array();
            $regexp = '/' . $filterinvalidprefixes . '(' . $linkobject->work_phrase . ')|(' . $linkobject->work_phrase . ')' . $filterinvalidsuffixes . '/' . $modifiers;
            preg_match_all($regexp, $text, $list_of_notfullmatches);
            if ($list_of_notfullmatches) {
                foreach (array_unique($list_of_notfullmatches[0]) as $key => $value) {
                    $notfullmatches['<*' . $key . '*>'] = $value;
                }
                if (!empty($notfullmatches)) {
                    $text = str_replace($notfullmatches, array_keys($notfullmatches), $text);
                }
            }
        }
        // Finally we do our highlighting
        if (!empty($CFG->filtermatchonepertext) || !empty($CFG->filtermatchoneperpage)) {
            $resulttext = preg_replace('/(' . $linkobject->work_phrase . ')/' . $modifiers, $linkobject->work_hreftagbegin . $linkobject->work_replacementphrase . $linkobject->work_hreftagend, $text, 1);
        } else {
            $resulttext = preg_replace('/(' . $linkobject->work_phrase . ')/' . $modifiers, $linkobject->work_hreftagbegin . $linkobject->work_replacementphrase . $linkobject->work_hreftagend, $text);
        }
        // If the text has changed we have to look for links again
        if ($resulttext != $text) {
            // Set $text to $resulttext
            $text = $resulttext;
            // Remove everything enclosed by the ignore tags from $text
            filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
            // Remove tags from $text
            filter_save_tags($text, $tags);
            // If $CFG->filtermatchoneperpage, save linked phrases to request
            if (!empty($CFG->filtermatchoneperpage)) {
                $usedphrases[] = $linkobject->work_phrase;
            }
        }
        // Replace the not full matches before cycling to next link object
        if (!empty($notfullmatches)) {
            $text = str_replace(array_keys($notfullmatches), $notfullmatches, $text);
            unset($notfullmatches);
        }
    }
    // Rebuild the text with all the excluded areas
    if (!empty($tags)) {
        $text = str_replace(array_keys($tags), $tags, $text);
    }
    if (!empty($ignoretags)) {
        $ignoretags = array_reverse($ignoretags);
        // Reversed so "progressive" str_replace() will solve some nesting problems.
        $text = str_replace(array_keys($ignoretags), $ignoretags, $text);
    }
    // Remove the protective doubleups
    $text = preg_replace('/([#*%])(\\1)/', '\\1', $text);
    // Add missing javascript for popus
    $text = filter_add_javascript($text);
    return $text;
}
Пример #2
0
/**
 * Given some text this function converts any URLs it finds into HTML links
 *
 * @param string $text Passed in by reference. The string to be searched for urls.
 */
function convert_urls_into_links(&$text)
{
    //I've added img tags to this list of tags to ignore.
    //See MDL-21168 for more info. A better way to ignore tags whether or not
    //they are escaped partially or completely would be desirable. For example:
    //<a href="blah">
    //&lt;a href="blah"&gt;
    //&lt;a href="blah">
    $filterignoretagsopen = array('<a\\s[^>]+?>');
    $filterignoretagsclose = array('</a>');
    filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
    // Check if we support unicode modifiers in regular expressions. Cache it.
    // TODO: this check should be a environment requirement in Moodle 2.0, as far as unicode
    // chars are going to arrive to URLs officially really soon (2010?)
    // Original RFC regex from: http://www.bytemycode.com/snippets/snippet/796/
    // Various ideas from: http://alanstorm.com/url_regex_explained
    // Unicode check, negative assertion and other bits from Moodle.
    static $unicoderegexp;
    if (!isset($unicoderegexp)) {
        $unicoderegexp = @preg_match('/\\pL/u', 'a');
        // This will fail silenty, returning false,
    }
    $unicoderegexp = false;
    //force non use of unicode modifiers. MDL-21296
    if ($unicoderegexp) {
        //We can use unicode modifiers
        $text = preg_replace('#(?<!=["\'])(((http(s?))://)(((([\\pLl0-9]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl0-9])\\.)+([\\pLl]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl]))|(([0-9]{1,3}\\.){3}[0-9]{1,3}))(:[\\pL0-9]*)?(/([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-fA-F0-9]{2})*)*(\\?([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,\\.;])#iu', '<a href="\\1" target="_blank">\\1</a>', $text);
        $text = preg_replace('#(?<!=["\']|//)((www\\.([\\pLl0-9]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl0-9])\\.)+([\\pLl]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl])(:[\\pL0-9]*)?(/([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-fA-F0-9]{2})*)*(\\?([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,\\.;])#iu', '<a href="http://\\1" target="_blank">\\1</a>', $text);
    } else {
        //We cannot use unicode modifiers
        $text = preg_replace('#(?<!=["\'])(((http(s?))://)(((([a-z0-9]([a-z0-9]|-)*[a-z0-9]|[a-z0-9])\\.)+([a-z]([a-z0-9]|-)*[a-z0-9]|[a-z]))|(([0-9]{1,3}\\.){3}[0-9]{1,3}))(:[a-zA-Z0-9]*)?(/([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})*)*(\\?([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,\\.;])#i', '<a href="\\1" target="_blank">\\1</a>', $text);
        $text = preg_replace('#(?<!=["\']|//)((www\\.([a-z0-9]([a-z0-9]|-)*[a-z0-9]|[a-z0-9])\\.)+([a-z]([a-z0-9]|-)*[a-z0-9]|[a-z])(:[a-zA-Z0-9]*)?(/([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})*)*(\\?([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,\\.;])#i', '<a href="http://\\1" target="_blank">\\1</a>', $text);
    }
    if (!empty($ignoretags)) {
        $ignoretags = array_reverse($ignoretags);
        /// Reversed so "progressive" str_replace() will solve some nesting problems.
        $text = str_replace(array_keys($ignoretags), $ignoretags, $text);
    }
}
Пример #3
0
 /**
  * Given some text this function converts any URLs it finds into HTML links
  *
  * @param string $text Passed in by reference. The string to be searched for urls.
  */
 protected function convert_urls_into_links(&$text)
 {
     //I've added img tags to this list of tags to ignore.
     //See MDL-21168 for more info. A better way to ignore tags whether or not
     //they are escaped partially or completely would be desirable. For example:
     //<a href="blah">
     //&lt;a href="blah"&gt;
     //&lt;a href="blah">
     $filterignoretagsopen = array('<a\\s[^>]+?>');
     $filterignoretagsclose = array('</a>');
     filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
     // Check if we support unicode modifiers in regular expressions. Cache it.
     // TODO: this check should be a environment requirement in Moodle 2.0, as far as unicode
     // chars are going to arrive to URLs officially really soon (2010?)
     // Original RFC regex from: http://www.bytemycode.com/snippets/snippet/796/
     // Various ideas from: http://alanstorm.com/url_regex_explained
     // Unicode check, negative assertion and other bits from Moodle.
     static $unicoderegexp;
     if (!isset($unicoderegexp)) {
         $unicoderegexp = @preg_match('/\\pL/u', 'a');
         // This will fail silently, returning false,
     }
     // TODO MDL-21296 - use of unicode modifiers may cause a timeout
     $urlstart = '(?:http(s)?://|(?<!://)(www\\.))';
     $domainsegment = '(?:[\\pLl0-9][\\pLl0-9-]*[\\pLl0-9]|[\\pLl0-9])';
     $numericip = '(?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3})';
     $port = '(?::\\d*)';
     $pathchar = '(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})';
     $path = "(?:/{$pathchar}*)*";
     $querystring = '(?:\\?(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)';
     $fragment = '(?:\\#(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)';
     // Lookbehind assertions.
     // Is not HTML attribute or CSS URL property. Unfortunately legit text like "url(http://...)" will not be a link.
     $lookbehindstart = "(?<!=[\"']|\\burl\\([\"' ]|\\burl\\()";
     $lookbehindend = "(?<![]),.;])";
     $regex = "{$lookbehindstart}{$urlstart}((?:{$domainsegment}\\.)+{$domainsegment}|{$numericip})" . "({$port}?{$path}{$querystring}?{$fragment}?){$lookbehindend}";
     if ($unicoderegexp) {
         $regex = '#' . $regex . '#ui';
     } else {
         $regex = '#' . preg_replace(array('\\pLl', '\\PL'), 'a-z', $regex) . '#i';
     }
     $text = preg_replace($regex, '<a href="http$1://$2$3$4" class="_blanktarget">$0</a>', $text);
     if (!empty($ignoretags)) {
         $ignoretags = array_reverse($ignoretags);
         /// Reversed so "progressive" str_replace() will solve some nesting problems.
         $text = str_replace(array_keys($ignoretags), $ignoretags, $text);
     }
     if ($this->get_global_config('embedimages')) {
         // now try to inject the images, this code was originally in the mediapluing filter
         // this may be useful only if somebody relies on the fact the links in FORMAT_MOODLE get converted
         // to URLs which in turn change to real images
         $search = '/<a href="([^"]+\\.(jpg|png|gif))" class="_blanktarget">([^>]*)<\\/a>/is';
         $text = preg_replace_callback($search, 'filter_urltolink_img_callback', $text);
     }
 }
Пример #4
0
 /**
  * Given some text this function converts any URLs it finds into HTML links
  *
  * @param string $text Passed in by reference. The string to be searched for urls.
  */
 protected function convert_urls_into_links(&$text)
 {
     //I've added img tags to this list of tags to ignore.
     //See MDL-21168 for more info. A better way to ignore tags whether or not
     //they are escaped partially or completely would be desirable. For example:
     //<a href="blah">
     //&lt;a href="blah"&gt;
     //&lt;a href="blah">
     $filterignoretagsopen = array('<a\\s[^>]+?>');
     $filterignoretagsclose = array('</a>');
     filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
     // Check if we support unicode modifiers in regular expressions. Cache it.
     // TODO: this check should be a environment requirement in Moodle 2.0, as far as unicode
     // chars are going to arrive to URLs officially really soon (2010?)
     // Original RFC regex from: http://www.bytemycode.com/snippets/snippet/796/
     // Various ideas from: http://alanstorm.com/url_regex_explained
     // Unicode check, negative assertion and other bits from Moodle.
     static $unicoderegexp;
     if (!isset($unicoderegexp)) {
         $unicoderegexp = @preg_match('/\\pL/u', 'a');
         // This will fail silently, returning false,
     }
     // TODO MDL-21296 - use of unicode modifiers may cause a timeout
     $urlstart = '(?:http(s)?://|(?<!://)(www\\.))';
     $domainsegment = '(?:[\\pLl0-9][\\pLl0-9-]*[\\pLl0-9]|[\\pLl0-9])';
     $numericip = '(?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3})';
     $port = '(?::\\d*)';
     $pathchar = '(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})';
     $path = "(?:/{$pathchar}*)*";
     $querystring = '(?:\\?(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)';
     $fragment = '(?:\\#(?:[\\pL0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)';
     // Lookbehind assertions.
     // Is not HTML attribute or CSS URL property. Unfortunately legit text like "url(http://...)" will not be a link.
     $lookbehindend = "(?<![]),.;])";
     $regex = "{$urlstart}((?:{$domainsegment}\\.)+{$domainsegment}|{$numericip})" . "({$port}?{$path}{$querystring}?{$fragment}?){$lookbehindend}";
     if ($unicoderegexp) {
         $regex = '#' . $regex . '#ui';
     } else {
         $regex = '#' . preg_replace(array('\\pLl', '\\PL'), 'a-z', $regex) . '#i';
     }
     // Locate any HTML tags.
     $matches = preg_split('/(<[^<|>]*>)/i', $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
     // Iterate through the tokenized text to handle chunks (html and content).
     foreach ($matches as $idx => $chunk) {
         // Nothing to do. We skip completely any html chunk.
         if (strpos(trim($chunk), '<') === 0) {
             continue;
         }
         // Nothing to do. We skip any content chunk having any of these attributes.
         if (preg_match('#(background=")|(action=")|(style="background)|(href=")|(src=")|(url [(])#', $chunk)) {
             continue;
         }
         // Arrived here, we want to process every word in this chunk.
         $text = $chunk;
         $words = explode(' ', $text);
         foreach ($words as $idx2 => $word) {
             // ReDoS protection. Stop processing if a word is too large.
             if (strlen($word) < 4096) {
                 $words[$idx2] = preg_replace($regex, '<a href="http$1://$2$3$4" class="_blanktarget">$0</a>', $word);
             }
         }
         $text = implode(' ', $words);
         // Copy the result back to the array.
         $matches[$idx] = $text;
     }
     $text = implode('', $matches);
     if (!empty($ignoretags)) {
         $ignoretags = array_reverse($ignoretags);
         /// Reversed so "progressive" str_replace() will solve some nesting problems.
         $text = str_replace(array_keys($ignoretags), $ignoretags, $text);
     }
     if (get_config('filter_urltolink', 'embedimages')) {
         // now try to inject the images, this code was originally in the mediapluing filter
         // this may be useful only if somebody relies on the fact the links in FORMAT_MOODLE get converted
         // to URLs which in turn change to real images
         $search = '/<a href="([^"]+\\.(jpg|png|gif))" class="_blanktarget">([^>]*)<\\/a>/is';
         $text = preg_replace_callback($search, 'filter_urltolink_img_callback', $text);
     }
 }
Пример #5
0
 /**
  * Given some text this function converts any URLs it finds into HTML links
  *
  * @param string $text Passed in by reference. The string to be searched for urls.
  */
 protected function convert_urls_into_links(&$text)
 {
     //I've added img tags to this list of tags to ignore.
     //See MDL-21168 for more info. A better way to ignore tags whether or not
     //they are escaped partially or completely would be desirable. For example:
     //<a href="blah">
     //&lt;a href="blah"&gt;
     //&lt;a href="blah">
     $filterignoretagsopen = array('<a\\s[^>]+?>');
     $filterignoretagsclose = array('</a>');
     filter_save_ignore_tags($text, $filterignoretagsopen, $filterignoretagsclose, $ignoretags);
     // Check if we support unicode modifiers in regular expressions. Cache it.
     // TODO: this check should be a environment requirement in Moodle 2.0, as far as unicode
     // chars are going to arrive to URLs officially really soon (2010?)
     // Original RFC regex from: http://www.bytemycode.com/snippets/snippet/796/
     // Various ideas from: http://alanstorm.com/url_regex_explained
     // Unicode check, negative assertion and other bits from Moodle.
     static $unicoderegexp;
     if (!isset($unicoderegexp)) {
         $unicoderegexp = @preg_match('/\\pL/u', 'a');
         // This will fail silently, returning false,
     }
     //todo: MDL-21296 - use of unicode modifiers may cause a timeout
     if ($unicoderegexp) {
         //We can use unicode modifiers
         $text = preg_replace('#(?<!=["\'])(((http(s?))://)(((([\\pLl0-9]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl0-9])\\.)+([\\pLl]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl]))|(([0-9]{1,3}\\.){3}[0-9]{1,3}))(:[\\pL0-9]*)?(/([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-fA-F0-9]{2})*)*(\\?([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,.;])#iu', '<a href="\\1" class="_blanktarget">\\1</a>', $text);
         $text = preg_replace('#(?<!=["\']|//)((www\\.([\\pLl0-9]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl0-9])\\.)+([\\pLl]([\\pLl0-9]|-)*[\\pLl0-9]|[\\pLl])(:[\\pL0-9]*)?(/([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-fA-F0-9]{2})*)*(\\?([\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[\\pLl0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,.;])#iu', '<a href="http://\\1" class="_blanktarget">\\1</a>', $text);
     } else {
         //We cannot use unicode modifiers
         $text = preg_replace('#(?<!=["\'])(((http(s?))://)(((([a-z0-9]([a-z0-9]|-)*[a-z0-9]|[a-z0-9])\\.)+([a-z]([a-z0-9]|-)*[a-z0-9]|[a-z]))|(([0-9]{1,3}\\.){3}[0-9]{1,3}))(:[a-zA-Z0-9]*)?(/([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})*)*(\\?([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,.;])#i', '<a href="\\1" class="_blanktarget">\\1</a>', $text);
         $text = preg_replace('#(?<!=["\']|//)((www\\.([a-z0-9]([a-z0-9]|-)*[a-z0-9]|[a-z0-9])\\.)+([a-z]([a-z0-9]|-)*[a-z0-9]|[a-z])(:[a-zA-Z0-9]*)?(/([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@-]|%[a-f0-9]{2})*)*(\\?([a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]|%[a-fA-F0-9]{2})*)?(\\#[a-z0-9\\.!$&\'\\(\\)*+,;=_~:@/?-]*)?)(?<![,.;])#i', '<a href="http://\\1" class="_blanktarget">\\1</a>', $text);
     }
     if (!empty($ignoretags)) {
         $ignoretags = array_reverse($ignoretags);
         /// Reversed so "progressive" str_replace() will solve some nesting problems.
         $text = str_replace(array_keys($ignoretags), $ignoretags, $text);
     }
     if ($this->get_global_config('embedimages')) {
         // now try to inject the images, this code was originally in the mediapluing filter
         // this may be useful only if somebody relies on the fact the links in FORMAT_MOODLE get converted
         // to URLs which in turn change to real images
         $search = '/<a href="([^"]+\\.(jpg|png|gif))" class="_blanktarget">([^>]*)<\\/a>/is';
         $text = preg_replace_callback($search, 'filter_urltolink_img_callback', $text);
     }
 }