Re: preg_replace brain teaser

From: Date: Tue, 15 Apr 2003 16:30:51 +0000
Subject: Re: preg_replace brain teaser
References: 1  Groups: php.general 
Request: Send a blank email to php-general+get-143978@lists.php.net to get a copy of this message
Hi, Wednesday, April 16, 2003, 12:58:38 AM, you wrote: Ssd> Hello Everyone Ssd> I have a slight problem with a regular expression for a preg_replace. Ssd> I'm trying to match arguments within a string and replace them with a Ssd> value from an array I pass to a function. Ssd> Arguments are enclosed in curly braces. Ssd> To make it clear here is an example: Ssd> "The dog ate {amount} ducks for dinner and got {feel}." Ssd> I pass the above string to a function parseArgument Ssd> $args = array('amount'=>'four', Ssd> 'feel'=>'sick'); Ssd> function parseArgument($string, $args) Ssd> { Ssd> return preg_replace('/\{([a-zA-Z0-9_-]+?)\}/e', Ssd> '$args[\\1]', $string); Ssd> } Ssd> which should return the result Ssd> "The dog ate four ducks for dinner and got sick." Ssd> So far it works. Ssd> Now I have the problem that opening braces have to be escaped when Ssd> included in the text. I choose '\' as the escape character. Ssd> So "The dog \{{amount}} ducks for dinner and got {feel}." passed to the Ssd> above function should return Ssd> "The dog {four} ducks for dinner and got sick." Ssd> In order to do this I changed the pattern from "\{([a-zA-Z0-9_-]+?)\}" to Ssd> "(?<!\\)\{([a-zA-Z0-9_-]+?)\}" which Ssd> results in an error: Ssd> Warning: Compilation failed: lookbehind assertion is not fixed length at Ssd> offset 31 in d:\eclipse_21\workspace\webframework\classes\I18N.class.php Ssd> on line 320 Ssd> First question (this is slightly off topic) I have is why is the Ssd> lookbehind not a fixed length? It should only be one '\'. Is this a bug in Ssd> the regex engine or am I missing something? Ssd> Second question is there a pattern that does the job for me? Ssd> IMPORTANT: The names in the curly brackets may only contain letters, Ssd> digits, and '-','_' as stated in the pattern. Ssd> I have a work around that replaces all occurences of escaped '{' with a Ssd> differnet pattern such as %%$$%% using str_replace and after doing the Ssd> preg_replace Ssd> switching them back. It seems a bit clumsy! SO my goal is to do it all in Ssd> one regex!!! Ssd> Thanks for your help in advance Ssd> Stefan Langer Ssd> P.S.: Please CC me (slanger at spirit21.de) when replying since I'm on Ssd> digest. You might want to try preg_replace_calback() as it is quite a bit faster. example: $args = array('amount'=>'four', 'feel'=>'sick'); $string = "The dog ate {amount} ducks for dinner and got {feel}."; function replace($match){ //$match[0] will be '{variable}' //$match[1] will be 'variable' global $args; if(isset($args[$match[1]])) return $args[$match[1]]; else return ''; } $new_string = preg_replace_callback('/\{(\w+)\}/','replace',$string); (note I am not a regex guru but you should get the idea :) -- regards, Tom

« previous php.general (#143978) next »