Jump to content

Dynamic backreferences?


448191

Recommended Posts

$result = preg_replace('/([A-Za-z]*)((_)([A-Za-z]*))*/', '$1::$4', $subject);

 

This only replaces the last match stored in $4. Makes sense, but is there a way I can avoid this without knowing how many times $4 will match?

 

Edit, never mind, I figured it out. I shouldn't repeat the expression in $4. I.e.:

 

Expr.

([A-Za-z]*)((_)([A-Za-z]*))

 

Repl.

 

$1::$4

 

Test

 

Zend_Db_Table_Abstract

 

Result

 

Zend::Db::Table::Abstract

 

:)

 

Link to comment
Share on other sites

If you are just trying to replace the underscore with '::', you could use a simple str_replace:

$str = 'Zend_Db_Table_Abstract';
$str = str_replace('_', '::', $str);
echo $str;

 

Unless I am not understanding something here.. I'm admittedly lost with what you want to achieve with $4...

EDIT:

 

When I test your expression with the source string as 'Zend_Db_Table_Abstract', I get:

Zend::Abstract::

 

Am I missing something?

 

Link to comment
Share on other sites

I can't replace underscores with double colons, because I'm processing whole classes (the whole of Zend Framework in fact).

 

The problem I had was that I didn't know how to combine a static part with a repeated part (e.g. Zend((_)([A-Za-z]*))). I still don't know how to do that, but it's ok, I've build around it.

 

Example:

 

<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category   Zend
* @package    Zend::Json
* @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license    http://framework.zend.com/license/new-bsd     New BSD License
*/

/**
* JsonException.
*/
require_once 'Zend/Json/Exception.php';

/**
* Class for encoding to and decoding from JSON.
*
* @category   Zend
* @package    Zend::Json
* @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license    http://framework.zend.com/license/new-bsd     New BSD License
*/
use Zend::Json::Exception JsonException;
use Zend::Json::Decoder;
use Zend::Json::Encoder;

namespace Zend;

class Json {
    /**
     * How objects should be encoded -- arrays or as StdClass. TYPE_ARRAY is 1
     * so that it is a boolean true value, allowing it to be used with
     * ext/json's functions.
     */
    const TYPE_ARRAY  = 1;
    const TYPE_OBJECT = 0;

     /**
      * To check the allowed nesting depth of the XML tree during xml2json conversion.
      * 
      * @var int
      */
    public static $maxRecursionDepthAllowed=25;

    /**
     * @var bool
     */
    public static $useBuiltinEncoderDecoder = false;

    /**
     * Decodes the given $encodedValue string which is
     * encoded in the JSON format
     *
     * Uses ext/json's json_decode if available.
     *
     * @param string $encodedValue Encoded in JSON format
     * @param int $objectDecodeType Optional; flag indicating how to decode
     * objects. See {@link ZJsonDecoder::decode()} for details.
     * @return mixed
     */
    public static function decode($encodedValue, $objectDecodeType = Zend::Json::TYPE_ARRAY)
    {
        if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
            return json_decode($encodedValue, $objectDecodeType);
        }

        require_once 'Zend/Json/Decoder.php';
        return Decoder::decode($encodedValue, $objectDecodeType);
    }


    /**
     * Encode the mixed $valueToEncode into the JSON format
     *
     * Encodes using ext/json's json_encode() if available.
     *
     * NOTE: Object should not contain cycles; the JSON format
     * does not allow object reference.
     *
     * NOTE: Only public variables will be encoded
     *
     * @param mixed $valueToEncode
     * @param boolean $cycleCheck Optional; whether or not to check for object recursion; off by default
     * @return string JSON encoded object
     */
    public static function encode($valueToEncode, $cycleCheck = false)
    {
        if (function_exists('json_encode') && self::$useBuiltinEncoderDecoder !== true) {
            return json_encode($valueToEncode);
        }

        require_once 'Zend/Json/Encoder.php';
        return Encoder::encode($valueToEncode, $cycleCheck);
    }

    /**  
     * fromXml - Converts XML to JSON  
     *  
     * Converts a XML formatted string into a JSON formatted string.   
     * The value returned will be a string in JSON format.  
     *  
     * The caller of this function needs to provide only the first parameter,   
     * which is an XML formatted String. The second parameter is optional, which   
     * lets the user to select if the XML attributes in the input XML string  
     * should be included or ignored in xml2json conversion.  
     *   
     * This function converts the XML formatted string into a PHP array by   
     * calling a recursive (protected static) function in this class. Then, it   
     * converts that PHP array into JSON by calling the "encode" static funcion.  
     *  
     * Throws a JsonException if the input not a XML formatted string.  
     *  
     * @static  
     * @access public  
     * @param string $xmlStringContents XML String to be converted  
     * @param boolean $ignoreXmlAttributes Include or exclude XML attributes in  
     * the xml2json conversion process.  
     * @return mixed - JSON formatted string on success  
     * @throws JsonException  
     */  
    public static function fromXml ($xmlStringContents, $ignoreXmlAttributes=true) {   
        // Load the XML formatted string into a Simple XML Element object.    
        $simpleXmlElementObject = simplexml_load_string($xmlStringContents);       
     
        // If it is not a valid XML content, throw an exception.      
        if ($simpleXmlElementObject == null) {      
            throw new JsonException('Function fromXml was called with an invalid XML formatted string.');   
        } // End of if ($simpleXmlElementObject == null)   
       
        $resultArray = null;   
         
        // Call the recursive function to convert the XML into a PHP array.   
        $resultArray = self::_processXml($simpleXmlElementObject, $ignoreXmlAttributes);             
  
        // Convert the PHP array to JSON using Zend::Json encode method.   
        // It is just that simple.   
        $jsonStringOutput = self::encode($resultArray);
        return($jsonStringOutput);       
    } // End of function fromXml.  

    /**  
     * _processXml - Contains the logic for xml2json  
     *  
     * The logic in this function is a recursive one.  
     *    
     * The main caller of this function (i.e. fromXml) needs to provide    
     * only the first two parameters i.e. the SimpleXMLElement object and   
     * the flag for ignoring or not ignoring XML attributes. The third parameter   
     * will be used internally within this function during the recursive calls.  
     *   
     * This function converts the SimpleXMLElement object into a PHP array by   
     * calling a recursive (protected static) function in this class. Once all  
     * the XML elements are stored in the PHP array, it is returned to the caller.  
     *  
     * Throws a JsonException if the XML tree is deeper than the allowed limit.  
     *  
     * @static  
     * @access protected  
     * @param SimpleXMLElement $simpleXmlElementObject XML element to be converted  
     * @param boolean $ignoreXmlAttributes Include or exclude XML attributes in  
     * the xml2json conversion process.  
     * @param int $recursionDepth Current recursion depth of this function
     * @return mixed - On success, a PHP associative array of traversed XML elements  
     * @throws JsonException  
     */  
    protected static function _processXml ($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) {       
        // Keep an eye on how deeply we are involved in recursion.      
        if ($recursionDepth > self::$maxRecursionDepthAllowed) {      
            // XML tree is too deep. Exit now by throwing an exception.      
            throw new JsonException(   
                "Function _processXml exceeded the allowed recursion depth of " .   
                self::$maxRecursionDepthAllowed);      
        } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed)     
     
        if ($recursionDepth == 0) {      
            // Store the original SimpleXmlElementObject sent by the caller.      
            // We will need it at the very end when we return from here for good.      
            $callerProvidedSimpleXmlElementObject = $simpleXmlElementObject;      
        } // End of if ($recursionDepth == 0)       
     
        if ($simpleXmlElementObject instanceof SimpleXMLElement) {      
            // Get a copy of the simpleXmlElementObject      
            $copyOfSimpleXmlElementObject = $simpleXmlElementObject;      
            // Get the object variables in the SimpleXmlElement object for us to iterate.      
            $simpleXmlElementObject = get_object_vars($simpleXmlElementObject);      
        } // End of if (get_class($simpleXmlElementObject) == "SimpleXMLElement")   
     
        // It needs to be an array of object variables.      
        if (is_array($simpleXmlElementObject)) {   
            // Initialize a result array.   
            $resultArray = array();      
            // Is the input array size 0? Then, we reached the rare CDATA text if any.      
            if (count($simpleXmlElementObject) <= 0) {      
                // Let us return the lonely CDATA. It could even be      
                // an empty element or just filled with whitespaces.      
                return (trim(strval($copyOfSimpleXmlElementObject)));      
            } // End of if (count($simpleXmlElementObject) <= 0)      
     
            // Let us walk through the child elements now.      
            foreach($simpleXmlElementObject as $key=>$value) {      
                // Check if we need to ignore the XML attributes.      
                // If yes, you can skip processing the XML attributes.      
                // Otherwise, add the XML attributes to the result array.      
                if(($ignoreXmlAttributes == true) && (is_string($key)) && ($key == "@attributes")) {      
                    continue;      
                } // End of if(($ignoreXmlAttributes == true) && ($key == "@attributes"))   
     
                // Let us recursively process the current XML element we just visited.      
                // Increase the recursion depth by one.      
                $recursionDepth++;       
                $resultArray[$key] = self::_processXml ($value, $ignoreXmlAttributes, $recursionDepth);      
     
                // Decrease the recursion depth by one.      
                $recursionDepth--;      
            } // End of foreach($simpleXmlElementObject as $key=>$value) {       
     
            if ($recursionDepth == 0) {      
                // That is it. We are heading to the exit now.      
                // Set the XML root element name as the root [top-level] key of      
                // the associative array that we are going to return to the original      
                // caller of this recursive function.      
                $tempArray = $resultArray;      
                $resultArray = array();      
                $resultArray[$callerProvidedSimpleXmlElementObject->getName()] = $tempArray;   
            } // End of if ($recursionDepth == 0)   
  
            return($resultArray);   
        } else {      
            // We are now looking at either the XML attribute text or      
            // the text between the XML tags.      
            return (trim(strval($simpleXmlElementObject)));      
        } // End of if (is_array($simpleXmlElementObject))      
    } // End of function _processXml. 
}

 

Am I missing something?

 

Delimiters perhaps?

 

 

Link to comment
Share on other sites

<pre>
<?php
$data = 'Zend_Db_Table_Abstract';
echo preg_replace('/\b([A-Za-z]+(?:_[A-Za-z]+)+)\b/e', 'join("::", explode("_", "$1"))', $data);
?>
</pre>

 

Update:

 

...is there a way I can avoid this without knowing how many times $4 will match?

 

It will use the last match saved into the backreference each time it needs to be used. If a new match is found by capturing parentheses, the previously saved match is overwritten.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.