Re: ereg_replace with user defined function?

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

 



Thanks again for your suggestions.

Actually, - believe it or not - I have never written a class (I am still learning PHP after three years working with that language). So I am not quite sure of the benefits of your class. One thing I do realise is the benefit of replacing the foreach loop with a single preg_replace_callbak. Let me try to sum up:

With a preg_replace_callback I am able to look for a pattern like: a number ( float or integer ) followed by whitespace followed by one, two, three or more characters, followed by a closing character.

e.g.: "((\d{1,10}[,|.]*\d{0,10})*(\s)(\D{1,3})([$|\s|.|,|\)|/]+| $))" (untested)

If preg finds a match, it will pass an array to the specified function. In that function I evaluate the unit, see if it is in my array containing the conversion "table". If that is the case, calculate the new value and return everything. Right?

I will get back with this new approach.

BTW, 0.32/0.34 seconds includes: calling the original html page from an outside server, loading this page into the DOM parser, walking through every table and every text string on that page. Convert everything necessary (the converter array contains about 14 metric -> imperial converters) replace all converted DOM nodes and output everything. The metric / imperial calculations / replacements take between 0.00054 and 0.005 seconds per table cell / text string.

/frank

11 okt 2006 kl. 13.39 skrev Roman Neuhauser:

# 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



........................................................................ ........................
Marketing Support & Webmaster

NIKE Hydraulics AB
Box 1107
631 80 Eskilstuna
Sweden

phone +46 - (0)16 16 82 34
fax +46 - (0)16 13 93 16
frank.arensmeier@xxxxxxxxxxxxxxxxx
www.nikehydraulics.se
........................................................................ ........................

--
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