preg_match: trying to identify number formats
I'm trying to identify not only "numbers" in a string, but tag what type of number it is, such as General, Fraction, Percentile, Ratio etc.
Now if I use a tool like http://rubular.com/, my patterns appear to work fine.
Rules?
([-+]?)([0-9]+)([,+]?)([.]?) //General
([-+]?[0-9.,]+[%]) //Percent
([0-9]+[\/][0-9]+(?:st|nd|rd|th)) //Fraction
([-+]?[0-9.,]+[:][-+]?[0-9.,]+) //Ratio
Strings to check?
1
1,000
1.000
-50.5
-1:+3
1,200.6:3.9
+2:-4
1/5th
25%
25.76%
1,001%
It's when I put them in php (if
/elseif
) constructs I always end up with the "general" number?
if (preg_match('/([-+]?[0-9.,]+[%])/',$string)) {
echo " PERCENTIL开发者_开发技巧E ";
} elseif (preg_match('/([0-9]+[\/][0-9]+(?:st|nd|rd|th))/',$string)) {
echo " FRACTION ";
} elseif (preg_match('/([-+]?[0-9.,]+[:][-+]?[0-9.,]+)/',$string)) {
echo " RATIO ";
} elseif (preg_match('/([-+]?)([0-9]+)([,+]?)([.]?)/',$string)) {
echo " CARDINAL ";
} else {
echo " GENERAL ";
}
No matter what, it echos "CARDINAL".
Yes, I've tried switching the order (Card/General first, then the others). Yes, I've tried making them independant IF()s, and in reverse order (most general first).
Nothing appears to work. Even a Single IF checking for any of the formats simply fails. Either my rules are stuffed - or I'm doing something blatantly wrong.
You error must come from somewhere else, I couldn't reproduce it. Try to put your code in an otherwise empty file to test it by itself and it should work fine.
Test.php:
$nums = array(
'1',
'1,000',
'1.000',
'-50.5',
'-1:+3',
'1,200.6:3.9',
'+2:-4',
'1/5th',
'25%',
'25.76%',
'1,001%'
);
foreach ($nums as $string) {
echo $string.': ';
if (preg_match('/([-+]?[0-9.,]+[%])/',$string)) {
echo " PERCENTILE ";
} elseif (preg_match('/([0-9]+[\/][0-9]+(?:st|nd|rd|th))/',$string)) {
echo " FRACTION ";
} elseif (preg_match('/([-+]?[0-9.,]+[:][-+]?[0-9.,]+)/',$string)) {
echo " RATIO ";
} elseif (preg_match('/([-+]?)([0-9]+)([,+]?)([.]?)/',$string)) {
echo " CARDINAL ";
} else {
echo " GENERAL ";
}
echo "\n";
}
$ php test.php
1: CARDINAL
1,000: CARDINAL
1.000: CARDINAL
-50.5: CARDINAL
-1:+3: RATIO
1,200.6:3.9: RATIO
+2:-4: RATIO
1/5th: FRACTION
25%: PERCENTILE
25.76%: PERCENTILE
1,001%: PERCENTILE
Try surrounding each regular expression with ^
and $
so that it matches only if it matches the entire string or line. Without these, if a regular expression matches part of a number, then that's still a match. For example, '1,000'
matches your regular expression for CARDINAL numbers, /([-+]?)([0-9]+)([,+]?)([.]?)/
, because it matches the substring '1,'
. If you add ^
and $
, as in /^([-+]?)([0-9]+)([,+]?)([.]?)$/
, then it no longer matches.
<?php
function check_format($string) {
if (preg_match('/^([-+]?[0-9.,]+[%])$/',$string)) {
echo " PERCENTILE ";
} elseif (preg_match('/^([0-9]+[\/][0-9]+(?:st|nd|rd|th))$/',$string)) {
echo " FRACTION ";
} elseif (preg_match('/^([-+]?[0-9.,]+[:][-+]?[0-9.,]+)$/',$string)) {
echo " RATIO ";
} elseif (preg_match('/^([-+]?)([0-9]+)([,+]?)([.]?)$/',$string)) {
echo " CARDINAL ";
} else {
echo " GENERAL ";
}
}
array_map("check_format", array(
"1",
"1,000",
"1.000",
"-50.5",
"-1:+3",
"1,200.6:3.9",
"+2:-4",
"1/5th",
"25%",
"25.76%",
"1,001%"
));
outputs:
CARDINAL GENERAL GENERAL GENERAL RATIO RATIO RATIO FRACTION PERCENTILE PERCENTILE PERCENTILE
EDIT: This might be a better regular expression for CARDINAL numbers:
/^([-+]?)([0-9]+)(?:,?[0-9]{3})*([.]?)$/
Please have a look on this .
<?php
$num = 12.20
$num = floatval(preg_replace('/[^\d.]/', '', num));
// output will be 12.2
//it always replace zero and you have number 12.00 then output will be 12
$num = 12.00
$num = floatval(preg_replace('/[^\d.]/', '', num));
// output will be 12
精彩评论