Re: [PHP] ereg_replace with user defined function?

2006-10-11 Thread Frank Arensmeier


10 okt 2006 kl. 19.25 skrev Roman Neuhauser:


# [EMAIL PROTECTED] / 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.




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


A page like this one: http://www.nikehydraulics.com/products/ 
product_chooser_gb.php?productMaingroup=5productSubgroup=33


.. gets converted within 0.32 / 0.34 seconds which I think is quite ok.

/frank



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



Re: [PHP] ereg_replace with user defined function?

2006-10-11 Thread Roman Neuhauser
# [EMAIL PROTECTED] / 2006-10-11 09:52:51 +0200:
 
 10 okt 2006 kl. 19.25 skrev Roman Neuhauser:
 
 # [EMAIL PROTECTED] / 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=5productSubgroup=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;
 

Re: [PHP] ereg_replace with user defined function?

2006-10-11 Thread Frank Arensmeier

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:


# [EMAIL PROTECTED] / 2006-10-11 09:52:51 +0200:


10 okt 2006 kl. 19.25 skrev Roman Neuhauser:


# [EMAIL PROTECTED] / 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=5productSubgroup=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 ( 

Re: [PHP] ereg_replace with user defined function?

2006-10-11 Thread Roman Neuhauser
# [EMAIL PROTECTED] / 2006-10-11 14:28:21 +0200:
 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.

Nevermind then. I don't know how to fit my experience into a short
email, so I'm not going to explain it, just replace the class with
whatever pays the bill.

 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)

that's wrong unless you want e. g. these to match:

1|2|3|4 (^)
00|,. [EMAIL PROTECTED]
 
 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?

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

(...) ok then

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



Re: [PHP] ereg_replace with user defined function?

2006-10-10 Thread Roman Neuhauser
# [EMAIL PROTECTED] / 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).

 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?

 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



Re: [PHP] ereg_replace with user defined function?

2006-10-09 Thread Frank Arensmeier
Thank you Ilaria and Roman for your input. I did not know that preg  
is able to deal with PCRE patterns. As a matter of fact I came up  
with the following solution (if someone is interested):


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

/frank

9 okt 2006 kl. 16.18 skrev Ilaria De Marinis:


Hi Frank,
I think preg_replace_callback is a good solution for you.

If you don't want to use it, you can construct two arrays defining  
matches and replacements.


For example:
$matches
[230]
[120]
[340]

$replacements
[9.1]
[replace2]
[replace3]



After you stored matches in $matches using regular expression like  
yours,/preg_match_all http://it.php.net/manual/en/function.preg- 
split.php/ (([[:digit:]]+|[[:digit:]]+\.[[:digit:]]+)([[:blank:]]?) 
(mm), $string, $matches, PREG_SET_ORDER)


you can define $replacements by this way:
for(int =0; icount($matches); i++){
   $replacements[$i]=round((substr($matches[$i][0], 0, 3)) 
*0.039370079),1); //take the last part of match with no digits, I  
don't know if there are sure 3 digits

}

for(int i=0; icount($matches); i++){
   preg_replace($string, $matches[$i][0], $replacement[$i].in);
}

hope to help you

Ilaria

Frank Arensmeier wrote:


Hello all.

Is it possible to have a user defined function for the  
replacement  within an ereg_replace (like preg_replace_callback)?  
I am working on  a script that converts html pages with metric  
data into imperial  data. My script takes text strings containing  
one or more instances  of e.g. 123 mm, 321 mm, 123 kg, 123  
cm2 and so on. The script  searches the string with a pattern like:

([[:digit:]]+|[[:digit:]]+\.[[:digit:]]+)([[:blank:]]?)(mm)

When the script finds an instance, it stores the matches into an   
array - ereg ( $pattern, $textstring, $matches )


The replacement (for mm) looks like:
round ( ( $matches[1] * 0.039370079 ), 1 ) . $matches[2]  . in

Everything is working great accept when the string contains more  
than  one instance for example of the metric unit mm. In that  
case, all  instances of xy mm will be replaced with the first  
occurrence.


So, a text like:

The product is 230 mm tall, 120 mm thick and 340 mm wide will   
output as The product is 9.1 in tall, 9.1 in thick and 9.1 in  
wide  - because the replacement string is based / calculated on  
the first  occurrence 230 mm.


Alternatively, is there a way to limit ereg_replace to only  
replace  one instance at a time?


Hopefully I am not too confusing...

regards,

/frank

ps. of course I have searched the manual and asked Google - no  
luck ds.





--

De Marinis Ilaria
Settore Automazione Biblioteche
Phone: +3906-44486052
CASPUR - Via dei Tizii ,6b - 00185 Roma
e-mail: [EMAIL PROTECTED]


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




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