SitePoint Sponsor

User Tag List

Results 1 to 19 of 19
  1. #1
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Replacing variable placeholders with array elements (preg_replace)

    Err, I'm trying to use a preg_replace to replace in a block of text, variable placeholders (of the form '[varname]') with their corresponding values from an array - the array key is the variable name.

    PHP Code:

    $code 
    "<h2>Foo is [foo] and bar is [bar].</h2>";

    $a['foo'] = 'bar'
    $a['bar'] = 'foo' 

    echo preg_replace("/\[(\S+)\]/e"$a["\$\\1"], $code); 
    That SHOULD output '<h2>Foo is bar and bar is foo.</h2>' but it isn't, it's just showing '<h2>Foo is and bar is .</h2>', which means the replacement's not being made properly. Can anyone help, please? The preg functions rock but I hate 'em, heh.

    Alex ...

  2. #2
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How about
    PHP Code:
    $GLOBALS['a'] = array('foo'=>'bar''bar'=>'foo');
    $subject '<h2>Foo is [foo] and bar is [bar].</h2>';
    $result preg_replace_callback(
      
    '/\[(\S+?)\]/'
      
    ,create_function('$matches''return @$GLOBALS["a"][$matches[1]];')
      ,
    $subject
      
    ); 
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  3. #3
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Isn't there an easier way to do this? I got it working once, and lost the file. I'd rather not work with the globals.. don't mean to sound ungrateful though.

  4. #4
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Call preg_replace in a loop, instead of all at once with the callback:
    PHP Code:
    $a = array('foo'=>'bar''bar'=>'foo');
    $result '<h2>Foo is [foo] and bar is [bar].</h2>';
    foreach(
    array_keys($a) as $key) {
      
    $result preg_replace(
        
    '/\['.preg_quote($key,'/').'\]/'
        
    ,$a[$key]
        ,
    $result
        
    );


  5. #5
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, that'd work too.. But there's a way of doing it, with one array, one string, and GAH! This is so frustrating. Thanks for your help man.

  6. #6
    SitePoint Zealot
    Join Date
    Mar 2004
    Location
    netherlands
    Posts
    104
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    <?php
    $string 
    '<h2>Foo is [foo] and bar is [bar].</h2>';
    $replacements = array('foo' => 'bar''bar' => 'foo');

    foreach(
    $replacements AS $key => $value)
    {
        
    $string str_replace('['.$key.']'$value$string);
    }

    echo 
    $string;
    ?>
    Maybe? Using preg_replace is a little over the top to do this.

  7. #7
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is str_replace faster in this case, then?

  8. #8
    SitePoint Zealot
    Join Date
    Mar 2004
    Location
    netherlands
    Posts
    104
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Im not sure if a loop with str_replace is faster then a single preg_replace. I know you can do array replacing all at once with one str_replace, but you'll have to investigate on that yourself if you want more information on that.

  9. #9
    SitePoint Zealot
    Join Date
    Jun 2003
    Location
    Elsewhere
    Posts
    107
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:

    echo preg_replace('/\[(\w+)\]/e''$a["\\1"]'$code); 
    Not 100% this would work: I don't have access to a running version of PHP ATM.

  10. #10
    SitePoint Enthusiast feti's Avatar
    Join Date
    Jun 2004
    Location
    Northeastern Ohio
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try this:


    $string = 'I am [foo] and [bar]';
    $needles = array('[foo]', '[bar]');
    $replacements = array('foo_replacement', 'bar_replacement');

    str_replace($needles, $replacements, $string);
    feti
    Mojavi Project - Mojavi 3.0.0-dev available now!

  11. #11
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I use the same thing as feti suggests which works very well. Normally I run through the arraykeys and just add the { and } to them and put them one array and use array_values to put the values into another array and use str_replace like feti does. I recon this is quicker than preg_replace myself, but I haven't benchmarked it. However, if this code is only used occasionally to render the odd error message, why should one care about this. If you are going to optimise for speed there will probably be many other areas in an app that could be optimised which can be highlighted using a profiler.

  12. #12
    SitePoint Enthusiast
    Join Date
    Mar 2004
    Location
    south
    Posts
    39
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's an example of using preg_replace from the excellent IS Layout [http://promoxy.mirrors.phpclasses.or...age/1514.html] templating class:

    /**
    * Replace an Element of HTML Code
    * @param string $Name Identification of element
    * @param mixed $args String or Array of values passed in identification
    * @param string $el HTML code for substitute the code between the element
    * @access private
    */
    function _Element_replace($Name, $args=NULL, $el=NULL)
    {
    if(is_array($args)){
    $comp="\s{1,}";
    foreach($args as $key=>$value)
    $comp.="$key=\"$value\"\s{0,}";
    }elseif($args!=NULL){
    $comp="\s{0,}".$args;
    $comp=preg_replace("[\s{1,}]","\s{1,}",$comp);
    }

    $preg="|<!-- $Name$comp(.*?)-->(.*?)<!-- end $Name -->|s";
    $this->_code=preg_replace($preg,$el,$this->_code);
    }
    Last edited by dvanatta; Dec 19, 2004 at 20:37. Reason: additonal text

  13. #13
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I use the method shown by feti and seconded by MiiJaySung. I haven't found anything that produces faster template benchmarks.

  14. #14
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you fellas, for all your help. What's infuriating is that I can get it to work with root-level variables, eg

    PHP Code:
    $foo 'foo';
    $bar 'bar';
    $string 'Foo is [foo] and bar is [bar]';
    $string preg_replace("/\[(\w+)\]/e""\$\\1"$string); 
    And I can do it with array indices:

    PHP Code:
    $a = array(=> 'foo''bar');
    $string 'Foo is [0] and bar is [1]';
    $string preg_replace("/\[(\d+)\]/",$a[(int) ${1}],$string); 
    But why can't I do it with array keys?!

  15. #15
    SitePoint Enthusiast
    Join Date
    Apr 2002
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's nice str_replace decision.

    PHP Code:
      function & parse($string$vars_ar) {
          foreach(
    $vars_ar as $k => $v) {
              
    $search[] = '[' $k ']';
              
    $replace[] = $v;
          }
          return 
    str_replace($search$replace$string);
      }
      
      
      
    $string '<h2>Foo is [foo] and bar is [bar].</h2>';
      
    $vars['foo'] = 'new_foo';
      
    $vars['bar'] = 'new_bar';
      
      echo 
    parse($string$vars); 

  16. #16
    SitePoint Zealot
    Join Date
    Jun 2003
    Location
    Elsewhere
    Posts
    107
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Copy-pasted directly from my own application:

    PHP Code:
    $querySet->query_string preg_replace'/\{(\w+)\}/e'"\$query_data['\\1']"$query_string ); 
    This works just fine in PHP5, and it should work in PHP4.

    So the next line should work for you, unless you're running some ancient version of PHP...

    PHP Code:
    $string preg_replace'/\[(\w+)\]/e'"\$a['\\1']"$string ); 

  17. #17
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    $string preg_replace('~\[\w+\]~e''@$a$0'$string

  18. #18
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Azmo and Stereofrog, THANK YOU. Finally.


  19. #19
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The keyword here is template-engine.
    If you need one - pick a package instead of reinventing the wheel. (smarty seems to be a popular choice - more lightweight alternatives exist, such as patTemplate). In fact you may not need one though - discover PHP as it's own template-engine with such tools as PHPSavant or SimpleT


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •