Ejemplo n.º 1
0
 /**
  * Decides for the given $pattern whether its a valid regular expression acceptable for
  * Arrays parser functions or not.
  *
  * @param string $pattern regular expression including delimiters and optional flags
  * @param bool   $forRegexFun whether the regular expression is inteded to be used with 'Regex Fun'
  *               if supported by the wikis infrastructure. In case 'Regex Fun' is not available,
  *               the default validation will be used.
  *
  * @return boolean
  */
 static function isValidRegEx($pattern, $forRegexFun = false)
 {
     if ($forRegexFun && self::hasRegexFunSupport()) {
         return ExtRegexFun::validateRegex($pattern);
     }
     if (!preg_match('/^([\\/\\|%]).*\\1[imsSuUx]*$/', $pattern)) {
         return false;
     }
     wfSuppressWarnings();
     // instead of using the evil @ operator!
     $isValid = false !== preg_match($pattern, ' ');
     // preg_match returns false on error
     wfRestoreWarnings();
     return $isValid;
 }
Ejemplo n.º 2
0
 /**
  * 'preg_replace'-like function but can handle special modifiers 'e' and 'r'.
  * 
  * @since 1.1
  * 
  * @param string  &$pattern
  * @param PPNode|string  $replacement should be a PPNode in case 'e' flag might be used since in that
  *                case the string will be expanded after back-refs are inserted. Otherwise string is ok.
  * @param string  $subject
  * @param int     $limit
  * @param Parser  &$parser if 'e' flag should be allowed, a parser object for parsing is required.
  * @param PPFrame $frame which keeps template parameters which should be used in case 'e' flag is set.
  * @param array   $allowedSpecialFlags all special flags that should be handled, by default 'e' and 'r'.
  */
 public static function doPregReplace($pattern, $replacement, $subject, $limit = -1, &$parser = null, $frame = null, array $allowedSpecialFlags = array(self::FLAG_REPLACEMENT_PARSE, self::FLAG_NO_REPLACE_NO_OUT))
 {
     static $lastPattern = null;
     static $activePattern = null;
     static $specialFlags = null;
     /*
      * cache validated pattern and use it as long as nothing has changed, this makes things
      * faster in case we do a lot of stuff with the same regex.
      */
     if ($lastPattern === null || $lastPattern !== $pattern) {
         // remember pattern without validation
         $lastPattern = $pattern;
         // if allowed special flags change, we have to validate again^^
         $lastFlags = implode(',', $allowedSpecialFlags);
         // validate regex and get special flags 'e' and 'r' if given:
         if (!self::validateRegex($pattern, $specialFlags)) {
             // invalid regex!
             $lastPattern = null;
             return false;
         }
         // set validated pattern as active one
         $activePattern = $pattern;
         // filter unwanted special flags:
         $allowedSpecialFlags = array_flip($allowedSpecialFlags);
         $specialFlags = array_intersect_key($specialFlags, $allowedSpecialFlags);
     } else {
         // set last validated pattern without flags 'e' and 'r'
         $pattern = $activePattern;
     }
     // make sure we have a frame to expand the $replacement (necessary for 'e' flag support!)
     if ($frame === null) {
         // new frame without template parameters then
         $frame = $parser->getPreprocessor()->newCustomFrame(array());
     }
     // FLAG 'e' (parse replace after match) handling:
     if (!empty($specialFlags[self::FLAG_REPLACEMENT_PARSE])) {
         // 'e' requires a Parser for parsing!
         if (!$parser instanceof Parser) {
             // no valid Parser object, without, we can't parse anything!
             throw new MWException("Regex Fun 'e' flag discovered but no Parser object given!");
         }
         // if 'e' flag is set, each replacement has to be parsed after matches are inserted but before replacing!
         self::$tmpRegexCB = array('replacement' => $replacement, 'parser' => &$parser, 'frame' => $frame, 'internal' => isset($parser->mExtRegexFun['lastMatches']) && $parser->mExtRegexFun['lastMatches'] === false);
         // do the actual replacement with special 'e' flag handling
         $output = preg_replace_callback($pattern, array(__CLASS__, 'doPregReplace_eFlag_callback'), $subject, $limit, $count);
     } else {
         $replacement = trim($frame->expand($replacement));
         // no 'e' flag, we can perform the standard function
         $output = preg_replace($pattern, $replacement, $subject, $limit, $count);
     }
     // FLAG 'r' (no replacement - no output) handling:
     if (!empty($specialFlags[self::FLAG_NO_REPLACE_NO_OUT])) {
         /*
          *  only output replacement result if there actually was a match and therewith a replacement happened
          * (otherwise the input string would be returned)
          */
         if ($count < 1) {
             return '';
         }
     }
     return $output;
 }