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; i<count($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; i<count($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: demarinis@xxxxxxxxx
------------------------------------------------
--
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