Re: ereg_replace with user defined function?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



# frank.arensmeier@xxxxxxxxxxxxxxxxx / 2006-10-11 09:52:51 +0200:
> 
> 10 okt 2006 kl. 19.25 skrev Roman Neuhauser:
> 
> ># frank.arensmeier@xxxxxxxxxxxxxxxxx / 2006-10-09 22:01:34 +0200:
> >>Thank you Ilaria and Roman for your input. I did not know that preg
> >>is able to deal with PCRE patterns.
> >
> >    "preg" is obviously short for "Perl REGular expressions", while
> >    PCRE positively means Perl-Compatible Regular Expressions.
> >    The regexp syntax from Perl is a superset of POSIX "extended"
> >    regexps, so anything ereg_ function accept will be good for
> >    preg_ as well (but beware of pattern delimiters).
> 
> Thanks for the info. I didn't know that.

    NP, glad to be of help. The relationship is quite obvious if you
    look at both syntaxes.

> >>As a matter of fact I came up
> >>with the following solution (if someone is interested):
> >
> >    What problem does it solve? I mean, why are you trying to avoid
> >    preg_replace_callback() in the first place?
> >
> 
> Maybe because I didn't know better?

    Well your question mentioned preg_replace_callback() so I thought
    maybe there was something about the function you didn't like.

> Initially, I was using  ereg_replace for replacing metric numbers with
> imperial ones. But  obviously, ereg_replace replaces all instances in
> the given text  string. A text containing more than one instance of
> the same unit,  was replaced by the calculated replacement string of
> the first  finding. So I had to think about other ways to do this -
> which  brought me to preg_replace_callback (as I already said - I
> didn't  know that preg takes POSIX patterns as well).
> 
> Would you suggest a different way? Would it be faster to do the  
> replacement with preg_replace_callback compared to the function I wrote?

    Definitely, and probably by several orders of magnitude.

> A page like this one: http://www.nikehydraulics.com/products/ 
> product_chooser_gb.php?productMaingroup=5&productSubgroup=33
> 
> .. gets converted within 0.32 / 0.34 seconds which I think is quite ok.

    If the time covers only the conversion then it's quite terrible.

    Looking at the convertTextString() function below there's a few
    obvious optimizations waiting to be done, and... turning the foreach
    into a single preg_replace_callback() is the one that begs
    implementing the most (the code below's been tested and works):

    class convertor
    {
        const SI_to_Imperial = 0;
        const Imperial_to_SI = 1;

        function convert($amount, $unit, $direction)
        {
            return sprintf(
                "whatever '%s' of '%s' is in the Imperial system"
              , $amount
              , $unit
            );
        }
    }
    function callbackSI2IS(array $SIspec)
    {
        return convertor::convert(
            $SIspec[1]
          , $SIspec[2]
          , convertor::SI_to_Imperial
        );
    }

    $p = '~
            ((?:\d+[,|.])*\d+) # amount
            \s*
            (m{1,2}\b) # meters or millis
         ~x';
    echo preg_replace_callback(
        $p
      , 'callbackSI2IS'
      , file_get_contents('php://stdin')
    );


> >>the function takes a text and an array with converters like:
> >>
> >>$converters[] = array (	"metric" => "mm", "imperial" => "in",
> >>"ratio"  => 0.039370079, "round" => 1 );
> >>$converters[] = array (	"metric" => "m", "imperial" => "ft", "ratio"
> >>=> 3.280839895, "round" => 1 );
> >>
> >>
> >>function convertTextString ( $text, $convertTable )
> >>{
> >>	# this function takes a text string, searches for numbers to
> >>convert, convert those numbers and returns
> >>	# the complete text again.
> >>
> >>	if ( !ereg ( "[[:digit:]]", $text ) ) // if the text does not
> >>contain any numbers, return the text as it is
> >>	{
> >>		return $text;
> >>	}
> >>	
> >>	foreach ( $convertTable as $convertKey => $convertUnit )
> >>	{
> >>		$pattern =
> >>		"((\d{1,10}[,|.]*\d{0,10})*(\s)(%s)([$|\s|.|,|\)|/]+| $))"; 
> >>		//  this regex
> >>looks for a number followed by white space,  followed by the  
> >>metric unit,
> >>followed by a closing character like  ".", "," or ")"
> >>		$pattern = sprintf ( $pattern, $convertUnit['metric'] );
> >>		
> >>		while ( preg_match ( $pattern, $text, $matches ) )
> >>		{
> >>			$matches[1] = str_replace ( ",", ".", $matches[1] );
> >>			// in case  numbers are written like "6,6 m", we 
> >>			need to  replace "," with
> >>"."
> >>			// because we do not want to return 0, we have to
> >>			make shure that  the new value is not zero.
> >>			$itterator = 0;
> >>			do {
> >>				$value = round ( ( $matches[1] *
> >>				$convertUnit['ratio'] ),  
> >>				$convertUnit['round'] + $itterator  );
> >>				++$itterator;
> >>			} while ( $value == 0 || $itterator == 10 );
> >>			
> >>			$replacement = $value . "$2" .
> >>			$convertUnit['imperial'] . "$4";
> >>			$text = preg_replace ( $pattern, $replacement,
> >>			$text, 1 );
> >>		}
> >>	}
> >>	return $text;
> >>}

-- 
How many Vietnam vets does it take to screw in a light bulb?
You don't know, man.  You don't KNOW.
Cause you weren't THERE.             http://bash.org/?255991

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux